diff --git a/src/api-impl-jni/android_app_NativeActivity.c b/src/api-impl-jni/android_app_NativeActivity.c index e9867285..99a34093 100644 --- a/src/api-impl-jni/android_app_NativeActivity.c +++ b/src/api-impl-jni/android_app_NativeActivity.c @@ -381,7 +381,6 @@ void Java_android_app_NativeActivity_onStartNative(JNIEnv* env, jobject clazz, j void Java_android_app_NativeActivity_onResumeNative(JNIEnv* env, jobject clazz, jlong handle) { - printf("STUB - onResume_native\n"); if (handle != 0) { struct NativeCode* code = (struct NativeCode*)handle; if (code->callbacks.onResume != NULL) { @@ -418,24 +417,22 @@ jbyteArray Java_android_app_NativeActivity_onSaveInstanceStateNative(JNIEnv* env void Java_android_app_NativeActivity_onPauseNative(JNIEnv* env, jobject clazz, jlong handle) { - printf("STUB - onPause_native\n"); -/* if (handle != 0) { + if (handle != 0) { struct NativeCode* code = (struct NativeCode*)handle; if (code->callbacks.onPause != NULL) { code->callbacks.onPause((ANativeActivity *)code); } - }*/ + } } void Java_android_app_NativeActivity_onStopNative(JNIEnv* env, jobject clazz, jlong handle) { - printf("STUB - onStop_native\n"); -/* if (handle != 0) { + if (handle != 0) { struct NativeCode* code = (struct NativeCode*)handle; if (code->callbacks.onStop != NULL) { code->callbacks.onStop((ANativeActivity *)code); } - }*/ + } } void Java_android_app_NativeActivity_onConfigurationChangedNative(JNIEnv* env, jobject clazz, jlong handle) diff --git a/src/api-impl-jni/app/android_app_Activity.c b/src/api-impl-jni/app/android_app_Activity.c index 3393f312..be49b809 100644 --- a/src/api-impl-jni/app/android_app_Activity.c +++ b/src/api-impl-jni/app/android_app_Activity.c @@ -28,9 +28,11 @@ static void activity_close(JNIEnv *env, jobject activity) static void activity_unfocus(JNIEnv *env, jobject activity) { - (*env)->CallVoidMethod(env, activity, handle_cache.activity.onPause); - if((*env)->ExceptionCheck(env)) - (*env)->ExceptionDescribe(env); + if(!_GET_BOOL_FIELD(activity, "paused")) { + (*env)->CallVoidMethod(env, activity, handle_cache.activity.onPause); + if((*env)->ExceptionCheck(env)) + (*env)->ExceptionDescribe(env); + } (*env)->CallVoidMethod(env, activity, handle_cache.activity.onStop); if((*env)->ExceptionCheck(env)) diff --git a/src/api-impl-jni/defines.h b/src/api-impl-jni/defines.h index f4e28685..ec6c6bb4 100644 --- a/src/api-impl-jni/defines.h +++ b/src/api-impl-jni/defines.h @@ -27,10 +27,12 @@ #define _SET_LONG_FIELD(object, field, value) ((*env)->SetLongField(env, object, _FIELD_ID(_CLASS(object), field, "J"), value)) #define _GET_LONG_FIELD(object, field) ((*env)->GetLongField(env, object, _FIELD_ID(_CLASS(object), field, "J"))) #define _SET_INT_FIELD(object, field, value) ((*env)->SetIntField(env, object, _FIELD_ID(_CLASS(object), field, "I"), value)) +#define _GET_INT_FIELD(object, field) ((*env)->GetIntField(env, object, _FIELD_ID(_CLASS(object), field, "I"))) +#define _SET_BOOL_FIELD(object, field, value) ((*env)->SetBooleanField(env, object, _FIELD_ID(_CLASS(object), field, "Z"), value)) +#define _GET_BOOL_FIELD(object, field) ((*env)->GetBooleanField(env, object, _FIELD_ID(_CLASS(object), field, "Z"))) #define _SET_STATIC_INT_FIELD(class, field, value) ((*env)->SetStaticIntField(env, class, _STATIC_FIELD_ID(class, field, "I"), value)) #define _SET_STATIC_OBJ_FIELD(class, field, type, value) ((*env)->SetStaticObjectField(env, class, _STATIC_FIELD_ID(class, field, type), value)) #define _GET_STATIC_OBJ_FIELD(class, field, type) ((*env)->GetStaticObjectField(env, class, _STATIC_FIELD_ID(class, field, type))) -#define _GET_INT_FIELD(object, field) ((*env)->GetIntField(env, object, _FIELD_ID(_CLASS(object), field, "I"))) #define _GET_BYTE_ARRAY_ELEMENTS(b_array) ((*env)->GetByteArrayElements(env, b_array, NULL)) #define _RELEASE_BYTE_ARRAY_ELEMENTS(b_array, buffer_ptr) ((*env)->ReleaseByteArrayElements(env, b_array, buffer_ptr, 0)) diff --git a/src/api-impl/android/app/Activity.java b/src/api-impl/android/app/Activity.java index e8ca4693..12475326 100644 --- a/src/api-impl/android/app/Activity.java +++ b/src/api-impl/android/app/Activity.java @@ -38,6 +38,7 @@ public class Activity extends ContextWrapper implements Window.Callback { private int pendingRequestCode; private int pendingResultCode; private Intent pendingData; + private boolean paused = false; List fragments = new ArrayList<>(); /** @@ -150,6 +151,7 @@ public class Activity extends ContextWrapper implements Window.Callback { fragment.onResume(); } + paused = false; return; } @@ -160,6 +162,7 @@ public class Activity extends ContextWrapper implements Window.Callback { fragment.onPause(); } + paused = true; return; } @@ -271,12 +274,17 @@ public class Activity extends ContextWrapper implements Window.Callback { try { Class cls = Class.forName(intent.getComponent().getClassName()).asSubclass(Activity.class); Constructor constructor = cls.getConstructor(); - Activity activity = constructor.newInstance(); + final Activity activity = constructor.newInstance(); activity.intent = intent; activity.getWindow().native_window = getWindow().native_window; activity.resultRequestCode = requestCode; activity.resultActivity = this; - nativeStartActivity(activity); + runOnUiThread(new Runnable() { + @Override + public void run() { + nativeStartActivity(activity); + } + }); } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { onActivityResult(requestCode, 0 /*RESULT_CANCELED*/, new Intent()); // RESULT_CANCELED is the only pre-defined return value, so hopefully it works out for us } @@ -303,7 +311,12 @@ public class Activity extends ContextWrapper implements Window.Callback { } public void finish() { - nativeFinish(getWindow().native_window); + runOnUiThread(new Runnable() { + @Override + public void run() { + nativeFinish(getWindow().native_window); + } + }); } public Object getLastNonConfigurationInstance() { diff --git a/src/api-impl/android/app/Dialog.java b/src/api-impl/android/app/Dialog.java index f665a55b..b529d2ff 100644 --- a/src/api-impl/android/app/Dialog.java +++ b/src/api-impl/android/app/Dialog.java @@ -76,10 +76,15 @@ public class Dialog implements Window.Callback, DialogInterface { } public void dismiss() { - System.out.println("dismissing the Dialog " + this); - nativeClose(nativePtr); - if (onDismissListener != null) - onDismissListener.onDismiss(this); + System.out.println("dismissing the Dialog " + Dialog.this); + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + nativeClose(nativePtr); + if (onDismissListener != null) + onDismissListener.onDismiss(Dialog.this); + } + }); } public Window getWindow() { diff --git a/src/api-impl/android/widget/AdapterView.java b/src/api-impl/android/widget/AdapterView.java index 427dad38..98deb9a5 100644 --- a/src/api-impl/android/widget/AdapterView.java +++ b/src/api-impl/android/widget/AdapterView.java @@ -28,6 +28,9 @@ public abstract class AdapterView extends ViewGroup { public void onItemClick(AdapterView parent, View view, int position, long id); } + public interface OnItemLongClickListener { + } + public void setAdapter(Adapter adapter) { this.adapter = adapter; } @@ -39,6 +42,8 @@ public abstract class AdapterView extends ViewGroup { public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {} + public void setOnItemLongClickListener(AdapterView.OnItemLongClickListener listener) {} + public void setSelection(int position, boolean animate) {} public Adapter getAdapter() { diff --git a/src/libandroid/asset_manager.c b/src/libandroid/asset_manager.c index 99ad77ff..0f748cf7 100644 --- a/src/libandroid/asset_manager.c +++ b/src/libandroid/asset_manager.c @@ -1,5 +1,5 @@ - #define _LARGEFILE64_SOURCE +#include #include #include #include @@ -20,6 +20,11 @@ struct AAsset{ off64_t read; }; +struct AAssetDir { + DIR *dp; + const char *dirname; +}; + typedef int64_t off64_t; typedef void JNIEnv; typedef void * jobject; @@ -40,7 +45,7 @@ int AAsset_openFileDescriptor(struct AAsset *asset, off_t *out_start, off_t *out 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 offet to a non-compressed archive member + *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; @@ -74,6 +79,56 @@ struct AAsset* AAssetManager_open(struct AAssetManager *amgr, const char *file_n return asset; } +struct AAssetDir * AAssetManager_openDir(struct AAssetManager *amgr, const char *dirname) +{ + char* app_data_dir = get_app_data_dir(); + char* dirpath = malloc(strlen(app_data_dir) + strlen(ASSET_DIR) + strlen(dirname) + 1); + struct AAssetDir* dir = malloc(sizeof(struct AAssetDir)); + dir->dirname = dirname; + + 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; + } + + return dir; +} + +const char * AAssetDir_getNextFileName(struct AAssetDir *dir) +{ + struct dirent *ep = readdir(dir->dp); + if (ep == NULL) + return NULL; + + if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..")) { + return AAssetDir_getNextFileName(dir); + } + + // 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;*/ + +} + + +void AAssetDir_close(struct AAssetDir *dir) +{ + closedir(dir->dp); + free(dir); +} + const void * AAsset_getBuffer(struct AAsset *asset) { int ret;