diff --git a/meson.build b/meson.build index e8132760..b3bd30c6 100644 --- a/meson.build +++ b/meson.build @@ -63,6 +63,9 @@ libandroid_so = shared_library('android', [ soversion: 0, dependencies: [ dependency('gtk4'), dependency('jni'), dependency('vulkan'), dependency('openxr').partial_dependency(includes: true) + ], + c_args: [ + '-D_LARGEFILE64_SOURCE', ]) libtranslationlayer_so = shared_library('translation_layer_main', [ @@ -142,6 +145,9 @@ libtranslationlayer_so = shared_library('translation_layer_main', [ link_with: [ libandroid_so ], link_args: [ '-lasound' + ], + c_args: [ + '-D_LARGEFILE64_SOURCE', ]) executable('android-translation-layer', [ diff --git a/src/api-impl-jni/android_app_NativeActivity.c b/src/api-impl-jni/android_app_NativeActivity.c index 297db88a..ebc991cc 100644 --- a/src/api-impl-jni/android_app_NativeActivity.c +++ b/src/api-impl-jni/android_app_NativeActivity.c @@ -138,9 +138,10 @@ struct NativeCode * NativeCode_new(void* _dlhandle, ANativeActivity_createFunc* return this; } -// FIXME: this is currently in libandroid.so, which is not necessarily requested by the app and therefore loaded +// FIXME: this is in libandroid.so, should use header files ANativeWindow * ANativeWindow_fromSurface(JNIEnv* env, jobject surface); void ANativeWindow_release(ANativeWindow *native_window); +struct AssetManager * AAssetManager_fromJava(JNIEnv *env, jobject asset_manager); void NativeCode_setSurface(struct NativeCode *this, jobject _surface) { @@ -334,7 +335,7 @@ jlong Java_android_app_NativeActivity_loadNativeCode(JNIEnv* env, jobject clazz, code->native_activity.sdkVersion = sdkVersion; - code->native_activity.assetManager = NULL;//assetManagerForJavaObject(env, jAssetMgr); + code->native_activity.assetManager = AAssetManager_fromJava(env, jAssetMgr); if (obbDir != NULL) { code->native_activity.obbPath = (*env)->GetStringUTFChars(env, obbDir, NULL); diff --git a/src/api-impl-jni/android_content_res_AssetManager.c b/src/api-impl-jni/android_content_res_AssetManager.c index f8b0b624..d4310d7f 100644 --- a/src/api-impl-jni/android_content_res_AssetManager.c +++ b/src/api-impl-jni/android_content_res_AssetManager.c @@ -18,100 +18,81 @@ #define ASSET_DIR "assets/" char *get_app_data_dir(); -JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_openAsset(JNIEnv *env, jobject this, jstring _file_name, jint mode) +JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_openAsset(JNIEnv *env, jobject this, jstring _file_name, jint mode) { const char *file_name = _CSTRING(_file_name); - /* handle absolute paths */ - if(file_name[0] == '/') - return open(file_name, O_CLOEXEC | O_RDWR); + struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject")); + struct Asset *asset = AssetManager_openNonAsset(asset_manager, file_name, mode); + printf("AssetManager_openAsset(%p, %s, %d)\n", asset_manager, file_name, mode); - char *app_data_dir = get_app_data_dir(); - char *path = malloc(strlen(app_data_dir) + strlen(ASSET_DIR) + strlen(file_name) + 1); + return _INTPTR(asset); +} + +JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_openAssetFd(JNIEnv *env, jobject this, jstring _file_name, jint mode, jlongArray _offset, jlongArray _size) +{ int fd; + off_t offset; + off_t size; - strcpy(path, app_data_dir); - strcat(path, ASSET_DIR); - strcat(path, file_name); + const char *file_name = _CSTRING(_file_name); - printf("openning asset with filename: %s\n", _CSTRING(_file_name)); + struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject")); + struct Asset *asset = AssetManager_openNonAsset(asset_manager, file_name, mode); + printf("AssetManager_openAssetFd(%p, %s, %d, ...)\n", asset_manager, file_name, mode); - printf("openning asset at path: %s\n", path); + fd = Asset_openFileDescriptor(asset, &offset, &size); - fd = open(path, O_CLOEXEC | O_RDWR); - - free(path); + (*env)->SetLongArrayRegion(env, _offset, 0, 1, (jlong[]){offset}); + (*env)->SetLongArrayRegion(env, _size, 0, 1, (jlong[]){size}); return fd; } -JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_getAssetLength(JNIEnv *env, jobject this, jint fd) +JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_getAssetLength(JNIEnv *env, jobject this, jlong _asset) { - int ret; - struct stat statbuf; - - ret = fstat(fd, &statbuf); - if(ret) - printf("oopsie, fstat failed on fd: %d with errno: %d\n", fd, errno); - - return statbuf.st_size; + struct Asset *asset = _PTR(_asset); + return Asset_getLength(asset); } -JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_getAssetRemainingLength(JNIEnv *env, jobject this, jint fd) +JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_getAssetRemainingLength(JNIEnv *env, jobject this, jlong _asset) { - jlong file_size = Java_android_content_res_AssetManager_getAssetLength(env, this, fd); - off_t offset = lseek(fd, 0, SEEK_CUR); - - return file_size - offset; + struct Asset *asset = _PTR(_asset); + return Asset_getRemainingLength(asset); } -JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_readAsset(JNIEnv *env, jobject this, jint fd, jbyteArray b, jint off, jint len) +JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_readAsset(JNIEnv *env, jobject this, jlong _asset, jbyteArray b, jlong offset, jlong length) { int ret; - int err; + struct Asset *asset = _PTR(_asset); jbyte *array = _GET_BYTE_ARRAY_ELEMENTS(b); - ret = read(fd, &array[off], len); + ret = Asset_read(asset, &array[offset], length); _RELEASE_BYTE_ARRAY_ELEMENTS(b, array); - if(ret < 0) { - err = errno; - printf("oopsie, read failed on fd: %d with errno: %d\n", fd, err); - exit(err); - } else if (ret == 0) { //EOF - return -1; - } else { - return ret; - } + return ret; } -JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_readAssetChar(JNIEnv *env, jobject this, jint fd) +JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_readAssetChar(JNIEnv *env, jobject this, jlong _asset) { int ret; - int err; - unsigned char byte; + uint8_t byte; - ret = read(fd, &byte, 1); - if(ret == 1) - return byte; - else if(ret == 0) - return -1; - else { - err = errno; - printf("oopsie, read failed on fd: %d with errno: %d\n", fd, err); - exit(err); - } + struct Asset *asset = _PTR(_asset); + ret = Asset_read(asset, &byte, 1); + return (ret == 1) ? byte : ret; } -JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_seekAsset(JNIEnv *env, jobject this, jint fd, jlong off, jint whence) +JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_seekAsset(JNIEnv *env, jobject this, jlong _asset, jlong offset, jint whence) { - return lseek(fd, off, (whence > 0) ? SEEK_END : (whence < 0 ? SEEK_SET : SEEK_CUR)); + struct Asset *asset = _PTR(_asset); + return Asset_seek(asset, offset, whence); } -JNIEXPORT void JNICALL Java_android_content_res_AssetManager_destroyAsset(JNIEnv *env, jobject this, jint fd) +JNIEXPORT void JNICALL Java_android_content_res_AssetManager_destroyAsset(JNIEnv *env, jobject this, jlong _asset) { - printf("closing asset with fd: %d\n", fd); - close(fd); + struct Asset *asset = _PTR(_asset); + Asset_delete(asset); } JNIEXPORT void JNICALL Java_android_content_res_AssetManager_init(JNIEnv *env, jobject this) diff --git a/src/api-impl-jni/generated_headers/android_content_res_AssetManager.h b/src/api-impl-jni/generated_headers/android_content_res_AssetManager.h index 1356d992..cf1c6608 100644 --- a/src/api-impl-jni/generated_headers/android_content_res_AssetManager.h +++ b/src/api-impl-jni/generated_headers/android_content_res_AssetManager.h @@ -124,74 +124,66 @@ JNIEXPORT jstring JNICALL Java_android_content_res_AssetManager_getResourceEntry /* * Class: android_content_res_AssetManager * Method: openAsset - * Signature: (Ljava/lang/String;I)I + * Signature: (Ljava/lang/String;I)J */ -JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_openAsset +JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_openAsset (JNIEnv *, jobject, jstring, jint); /* * Class: android_content_res_AssetManager * Method: openAssetFd - * Signature: (Ljava/lang/String;[J)Landroid/os/ParcelFileDescriptor; + * Signature: (Ljava/lang/String;I[J[J)I */ -JNIEXPORT jobject JNICALL Java_android_content_res_AssetManager_openAssetFd - (JNIEnv *, jobject, jstring, jlongArray); - -/* - * Class: android_content_res_AssetManager - * Method: openNonAssetFdNative - * Signature: (ILjava/lang/String;[J)Landroid/os/ParcelFileDescriptor; - */ -JNIEXPORT jobject JNICALL Java_android_content_res_AssetManager_openNonAssetFdNative - (JNIEnv *, jobject, jint, jstring, jlongArray); +JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_openAssetFd + (JNIEnv *, jobject, jstring, jint, jlongArray, jlongArray); /* * Class: android_content_res_AssetManager * Method: destroyAsset - * Signature: (I)V + * Signature: (J)V */ JNIEXPORT void JNICALL Java_android_content_res_AssetManager_destroyAsset - (JNIEnv *, jobject, jint); + (JNIEnv *, jobject, jlong); /* * Class: android_content_res_AssetManager * Method: readAssetChar - * Signature: (I)I + * Signature: (J)I */ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_readAssetChar - (JNIEnv *, jobject, jint); + (JNIEnv *, jobject, jlong); /* * Class: android_content_res_AssetManager * Method: readAsset - * Signature: (I[BII)I + * Signature: (J[BJJ)I */ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_readAsset - (JNIEnv *, jobject, jint, jbyteArray, jint, jint); + (JNIEnv *, jobject, jlong, jbyteArray, jlong, jlong); /* * Class: android_content_res_AssetManager * Method: seekAsset - * Signature: (IJI)J + * Signature: (JJI)J */ JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_seekAsset - (JNIEnv *, jobject, jint, jlong, jint); + (JNIEnv *, jobject, jlong, jlong, jint); /* * Class: android_content_res_AssetManager * Method: getAssetLength - * Signature: (I)J + * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_getAssetLength - (JNIEnv *, jobject, jint); + (JNIEnv *, jobject, jlong); /* * Class: android_content_res_AssetManager * Method: getAssetRemainingLength - * Signature: (I)J + * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_getAssetRemainingLength - (JNIEnv *, jobject, jint); + (JNIEnv *, jobject, jlong); /* * Class: android_content_res_AssetManager @@ -361,14 +353,6 @@ JNIEXPORT jintArray JNICALL Java_android_content_res_AssetManager_getArrayString JNIEXPORT void JNICALL Java_android_content_res_AssetManager_init (JNIEnv *, jobject); -/* - * Class: android_content_res_AssetManager - * Method: destroy - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_android_content_res_AssetManager_destroy - (JNIEnv *, jobject); - #ifdef __cplusplus } #endif diff --git a/src/api-impl/android/content/res/AssetManager.java b/src/api-impl/android/content/res/AssetManager.java index e4f44415..f9907f72 100644 --- a/src/api-impl/android/content/res/AssetManager.java +++ b/src/api-impl/android/content/res/AssetManager.java @@ -17,6 +17,7 @@ package android.content.res; import android.content.Context; +import android.os.Environment; import android.os.ParcelFileDescriptor; import android.util.AttributeSet; import android.util.Log; @@ -127,6 +128,7 @@ public final class AssetManager { } catch (IOException e) { Log.e(TAG, "failed to load resources.arsc" + e); } + addAssetPath(android.os.Environment.getExternalStorageDirectory().getAbsolutePath()); } } @@ -308,48 +310,12 @@ public final class AssetManager { * @see #list */ public final InputStream open(String fileName, int accessMode) throws IOException { - int asset; - // try loading from filesystem - synchronized (this) { - if (!mOpen) { - throw new RuntimeException("Assetmanager has been closed"); - } - asset = openAsset(fileName, accessMode); - if (asset >= 0) { - AssetInputStream res = new AssetInputStream(asset, "/assets/" + fileName); - incRefsLocked(res.hashCode()); - return res; - } - } - // alternatively load directly from APK - InputStream ret = ClassLoader.getSystemClassLoader().getResourceAsStream("assets/" + fileName); - if(ret == null) - throw new FileNotFoundException("Asset file: " + fileName + ", errno: " + asset); - - return ret; + long asset = openAsset("assets/" + fileName, accessMode); + return new AssetInputStream(asset); } - public final AssetFileDescriptor openFd(String fileName) - throws IOException { - int asset; - synchronized (this) { - if (!mOpen) { - throw new RuntimeException("Assetmanager has been closed"); - } - asset = openAsset(fileName, 0); - if (asset < 0) - throw new FileNotFoundException("Asset file: " + fileName + ", errno: " + asset); - - FileDescriptor fd = new FileDescriptor(); - fd.setInt$(asset); - ParcelFileDescriptor pfd = new ParcelFileDescriptor(fd); - if (pfd != null) { - AssetFileDescriptor afd = new AssetFileDescriptor(pfd, 0, getAssetLength(asset)); - afd.fileName = "/assets/" + fileName; - return afd; - } - } - throw new FileNotFoundException("Asset file: " + fileName); + public final AssetFileDescriptor openFd(String fileName) throws IOException { + return openFd_internal("assets/" + fileName, 0); } /** @@ -415,21 +381,8 @@ public final class AssetManager { * @param accessMode Desired access mode for retrieving the data. */ public final InputStream openNonAsset(int cookie, String fileName, int accessMode) throws IOException { - int asset; - // try loading from filesystem - synchronized (this) { - if (!mOpen) { - throw new RuntimeException("Assetmanager has been closed"); - } - asset = openNonAssetNative(cookie, fileName, accessMode); - if (asset >= 0) { - AssetInputStream res = new AssetInputStream(asset, fileName); - incRefsLocked(res.hashCode()); - return res; - } - } - // alternatively load directly from APK - return ClassLoader.getSystemClassLoader().getResourceAsStream(fileName); + long asset = openAsset(fileName, accessMode); + return new AssetInputStream(asset); } public final AssetFileDescriptor openNonAssetFd(String fileName) @@ -439,17 +392,33 @@ public final class AssetManager { public final AssetFileDescriptor openNonAssetFd(int cookie, String fileName) throws IOException { + return openFd_internal(fileName, 0); + + } + + private final AssetFileDescriptor openFd_internal(String fileName, int accessMode) + throws IOException { + int asset; synchronized (this) { if (!mOpen) { throw new RuntimeException("Assetmanager has been closed"); } - ParcelFileDescriptor pfd = openNonAssetFdNative(cookie, - fileName, mOffsets); + long[] offset = new long[1]; + long[] length = new long[1]; + asset = openAssetFd(fileName, accessMode, offset, length); + if (asset < 0) + throw new FileNotFoundException("file: " + fileName + ", error: " + asset); + + FileDescriptor fd = new FileDescriptor(); + fd.setInt$(asset); + ParcelFileDescriptor pfd = new ParcelFileDescriptor(fd); if (pfd != null) { - return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]); + AssetFileDescriptor afd = new AssetFileDescriptor(pfd, offset[0], length[0]); + afd.fileName = fileName; + return afd; } } - throw new FileNotFoundException("Asset absolute file: " + fileName); + throw new FileNotFoundException("file: " + fileName); } /** @@ -553,13 +522,9 @@ public final class AssetManager { } public final class AssetInputStream extends InputStream { - public final int getAssetInt() { - return mAsset; - } - private AssetInputStream(int asset, String fileName) { + private AssetInputStream(long asset) { mAsset = asset; mLength = getAssetLength(asset); - this.fileName = fileName; } public final int read() throws IOException { return readAssetChar(mAsset); @@ -607,10 +572,9 @@ public final class AssetManager { close(); } - private int mAsset; + private long mAsset; private long mLength; private long mMarkPos; - public String fileName; } /** @@ -720,20 +684,15 @@ public final class AssetManager { /*package*/ native final String getResourceTypeName(int resid); /*package*/ native final String getResourceEntryName(int resid); - private native final int openAsset(String fileName, int accessMode); - private final native ParcelFileDescriptor openAssetFd(String fileName, - long[] outOffsets) throws IOException; - private /*native*/ final int openNonAssetNative(int cookie, String fileName, int accessMode) { - return openAsset("../" + fileName, accessMode); - } - private native ParcelFileDescriptor openNonAssetFdNative(int cookie, - String fileName, long[] outOffsets) throws IOException; - private native final void destroyAsset(int asset); - private native final int readAssetChar(int asset); - private native final int readAsset(int asset, byte[] b, int off, int len); - private native final long seekAsset(int asset, long offset, int whence); - private native final long getAssetLength(int asset); - private native final long getAssetRemainingLength(int asset); + private native final long openAsset(String fileName, int accessMode); + private native final int openAssetFd(String fileName, int accessMode, long[] offset, long[] length); + + private native final void destroyAsset(long asset); + private native final int readAssetChar(long asset); + private native final int readAsset(long asset, byte[] b, long offset, long length); + private native final long seekAsset(long asset, long offset, int whence); + private native final long getAssetLength(long asset); + private native final long getAssetRemainingLength(long asset); /** * Returns true if the resource was found, filling in mRetStringBlock and @@ -894,7 +853,9 @@ public final class AssetManager { } private native final void init(); - private native final void destroy(); + private /*native*/ final void destroy() { + System.out.println("AssetManager.destroy(): STUB"); + } private final void incRefsLocked(int id) { if (DEBUG_REFS) { diff --git a/src/api-impl/android/graphics/BitmapFactory.java b/src/api-impl/android/graphics/BitmapFactory.java index 350290af..35e0512c 100644 --- a/src/api-impl/android/graphics/BitmapFactory.java +++ b/src/api-impl/android/graphics/BitmapFactory.java @@ -559,12 +559,7 @@ public class BitmapFactory { Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap"); try { - if (is instanceof AssetManager.AssetInputStream) { - final String fileName = ((AssetManager.AssetInputStream)is).fileName; - bm = new Bitmap(fileName); - } else { - bm = decodeStreamInternal(is, outPadding, opts); - } + bm = decodeStreamInternal(is, outPadding, opts); if (bm == null && opts != null && opts.inBitmap != null) { throw new IllegalArgumentException("Problem decoding into existing bitmap"); diff --git a/src/libandroid/asset_manager.c b/src/libandroid/asset_manager.c index 0f748cf7..6f984a90 100644 --- a/src/libandroid/asset_manager.c +++ b/src/libandroid/asset_manager.c @@ -1,4 +1,3 @@ -#define _LARGEFILE64_SOURCE #include #include #include @@ -7,208 +6,122 @@ #include #include #include +#include #include -struct AAssetManager { - char dummy; -}; +#include -struct AAssetManager dummy_asset_manager; - -struct AAsset{ - int fd; - off64_t read; -}; +#include "../api-impl-jni/defines.h" +#include "../api-impl-jni/util.h" struct AAssetDir { - DIR *dp; - const char *dirname; + struct AssetDir *asset_dir; + size_t curr_index; }; -typedef int64_t off64_t; -typedef void JNIEnv; -typedef void * jobject; - #define ASSET_DIR "assets/" -char *get_app_data_dir(); -int AAsset_openFileDescriptor(struct AAsset *asset, off_t *out_start, off_t *out_length) +int AAsset_openFileDescriptor(struct Asset *asset, off_t *out_start, off_t *out_length) { - int ret; - int fd = asset->fd; - - printf("openning asset's file descriptor: : %d\n", fd); - - struct stat statbuf; - - ret = fstat(fd, &statbuf); - if(ret) - printf("oopsie, fstat failed on fd: %d with errno: %d\n", fd, errno); - - *out_start = 0; // on android, we would be returning the fd of the app's apk, and this would be the offset to a non-compressed archive member - *out_length = statbuf.st_size; // similarly, this would be the size of the section of memory containing the non-compressed archive member - - return fd; + return Asset_openFileDescriptor(asset, out_start, out_length); } -struct AAsset* AAssetManager_open(struct AAssetManager *amgr, const char *file_name, int mode) +struct Asset* AAssetManager_open(struct AssetManager *asset_manager, const char *file_name, int mode) { - char *app_data_dir = get_app_data_dir(); - char *path = malloc(strlen(app_data_dir) + strlen(ASSET_DIR) + strlen(file_name) + 1); - int fd; - strcpy(path, app_data_dir); - strcat(path, ASSET_DIR); - strcat(path, file_name); + char *path = malloc(strlen(ASSET_DIR) + strlen(file_name) + 1); + sprintf(path, "%s%s", ASSET_DIR, file_name); - printf("openning asset with filename: %s\n", file_name); - - printf("openning asset at path: %s\n", path); - - fd = open(path, O_CLOEXEC | O_RDWR); - if(fd < 0) { - printf("oopsie, falied to open file: %s (errno: %d)\n", file_name, errno); - return NULL; - } + printf("AAssetManager_open called for %s\n", file_name); + struct Asset *asset = AssetManager_openNonAsset(asset_manager, path, mode); free(path); - struct AAsset* asset = malloc(sizeof(struct AAsset)); - asset->fd = fd; - asset->read = 0; - return asset; } -struct AAssetDir * AAssetManager_openDir(struct AAssetManager *amgr, const char *dirname) +const void * AAsset_getBuffer(struct Asset *asset) { - char* app_data_dir = get_app_data_dir(); - char* dirpath = malloc(strlen(app_data_dir) + strlen(ASSET_DIR) + strlen(dirname) + 1); + return Asset_getBuffer(asset, false); +} + +off64_t AAsset_getLength64(struct Asset *asset) +{ + return Asset_getLength(asset); +} + +off_t AAsset_getLength(struct Asset *asset) +{ + return Asset_getLength(asset); +} + +int AAsset_read(struct Asset *asset, void *buf, size_t count) { + return Asset_read(asset, buf, count); +} + +off_t AAsset_seek(struct Asset *asset, off_t offset, int whence) { + return Asset_seek(asset, offset, whence); +} + +off64_t AAsset_seek64(struct Asset *asset, off64_t offset, int whence) { + return Asset_seek(asset, offset, whence); +} + +off_t AAsset_getRemainingLength(struct Asset *asset) +{ + return Asset_getRemainingLength(asset); +} +off64_t AAsset_getRemainingLength64(struct Asset *asset) +{ + return Asset_getRemainingLength(asset); +} + +void AAsset_close(struct Asset *asset) +{ + Asset_delete(asset); +} + +struct AAssetDir * AAssetManager_openDir(struct AssetManager *asset_manager, const char *dirname) +{ + char* dirpath = malloc(strlen(ASSET_DIR) + strlen(dirname) + 1); + sprintf(dirpath, "%s%s", ASSET_DIR, dirname); + + struct AssetDir *asset_dir = AssetManager_openDir(asset_manager, dirname); + struct AAssetDir* dir = malloc(sizeof(struct AAssetDir)); - dir->dirname = dirname; + dir->asset_dir = asset_dir; + dir->curr_index = 0; - strcpy(dirpath, app_data_dir); - strcat(dirpath, ASSET_DIR); - strcat(dirpath, dirname); - printf("open directory path %s\n", dirpath); - - dir->dp = opendir(dirpath); - if (dir->dp < 0) - { - printf("failed to open directory %s: %d\n", dirpath, errno); - return NULL; - } + printf("AAssetManager_openDir called for %s\n", dirpath); return dir; } const char * AAssetDir_getNextFileName(struct AAssetDir *dir) { - struct dirent *ep = readdir(dir->dp); - if (ep == NULL) - return NULL; + size_t index = dir->curr_index; + const size_t max = AssetDir_getFileCount(dir->asset_dir); - if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..")) { - return AAssetDir_getNextFileName(dir); + /* skip non-regular files */ + while ((index < max) && AssetDir_getFileType(dir->asset_dir, index) != FILE_TYPE_REGULAR) + index++; + + if (index >= max) { + dir->curr_index = index; + return NULL; } - // google claims to return full path, but it really doesn't seem so - return ep->d_name; -/* char *asset_root_path = malloc(strlen(dir->dirname) + 1 + strlen(ep->d_name) + 1); - - sprintf(asset_root_path, "%s/%s", dir->dirname, ep->d_name); - printf("AAssetDir_getNextFileName: returning >%s<\n", asset_root_path); - - return asset_root_path;*/ - + dir->curr_index = index + 1; + return AssetDir_getFileName(dir->asset_dir, index); } void AAssetDir_close(struct AAssetDir *dir) { - closedir(dir->dp); + AssetDir_delete(dir->asset_dir); free(dir); } -const void * AAsset_getBuffer(struct AAsset *asset) +struct AssetManager * AAssetManager_fromJava(JNIEnv *env, jobject asset_manager) { - int ret; - int err; - int fd = asset->fd; - - struct stat statbuf; - - ret = fstat(fd, &statbuf); - if(ret) - printf("oopsie, fstat failed on fd: %d with errno: %d\n", fd, errno); - - uint8_t *buffer = malloc(statbuf.st_size); - ret = pread(fd, buffer, statbuf.st_size, 0); - if(ret < 0) { - err = errno; - printf("oopsie, read failed on fd: %d with errno: %d\n", fd, err); - exit(err); - } - - return buffer; -} - -off64_t AAsset_getLength64(struct AAsset *asset) -{ - int ret; - int fd = asset->fd; - - struct stat statbuf; - - ret = fstat(fd, &statbuf); - if(ret) - printf("oopsie, fstat failed on fd: %d with errno: %d\n", fd, errno); - - return statbuf.st_size; -} - -off_t AAsset_getLength(struct AAsset *asset) -{ - return AAsset_getLength64(asset); -} -struct AAssetManager * AAssetManager_fromJava(JNIEnv *env, jobject assetManager) -{ - // some apps don't like if we return NULL here - return &dummy_asset_manager; -} - -int AAsset_read(struct AAsset *asset, void *buf, size_t count) { - off64_t tmp = read(asset->fd, buf, count); - asset->read += tmp; - return tmp; -} - -off_t AAsset_seek(struct AAsset *asset, off_t offset, int whence) { - off64_t tmp = lseek(asset->fd, offset, whence); - asset->read += tmp; - return tmp; -} - -off64_t AAsset_seek64(struct AAsset *asset, off64_t offset, int whence) { - off64_t tmp = lseek64(asset->fd, offset, whence); - asset->read += tmp; - return tmp; -} - -off_t AAsset_getRemainingLength(struct AAsset* asset) -{ - return AAsset_getLength(asset) - asset->read; -} -off64_t AAsset_getRemainingLength64(struct AAsset* asset) -{ - return AAsset_getLength64(asset) - asset->read; -} - -void AAsset_close(struct AAsset *asset) -{ - int fd = asset->fd; - - printf("closing asset with fd: %d\n", fd); - close(fd); - - free(asset); + return _PTR(_GET_LONG_FIELD(asset_manager, "mObject")); } diff --git a/src/main-executable/main.c b/src/main-executable/main.c index 94b1e8d5..5dece6e3 100644 --- a/src/main-executable/main.c +++ b/src/main-executable/main.c @@ -403,7 +403,6 @@ static void open(GtkApplication *app, GFile** files, gint nfiles, const gchar* h if((*env)->ExceptionCheck(env)) (*env)->ExceptionDescribe(env); - extract_from_apk("assets/", "assets/"); /* extract native libraries from apk*/ if(!getenv("ATL_SKIP_NATIVES_EXTRACTION")) extract_from_apk("lib/" NATIVE_ARCH "/", "lib/");