From b101b01228231714e298e09a293a91b99892a6cd Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sat, 7 Sep 2024 15:51:37 -0400 Subject: [PATCH 1/3] chore: Bump all subproject compileSdks ...yes, we'll probably need to bump these again very soon. --- app-deps/build.gradle.kts | 2 +- libs/lpac-jni/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app-deps/build.gradle.kts b/app-deps/build.gradle.kts index 2111436..6cde72d 100644 --- a/app-deps/build.gradle.kts +++ b/app-deps/build.gradle.kts @@ -13,7 +13,7 @@ apply { android { namespace = "im.angry.openeuicc_deps" - compileSdk = 33 + compileSdk = 34 defaultConfig { minSdk = 28 diff --git a/libs/lpac-jni/build.gradle.kts b/libs/lpac-jni/build.gradle.kts index b50a953..7f45177 100644 --- a/libs/lpac-jni/build.gradle.kts +++ b/libs/lpac-jni/build.gradle.kts @@ -5,7 +5,7 @@ plugins { android { namespace = "net.typeblog.lpac_jni" - compileSdk = 33 + compileSdk = 34 ndkVersion = "26.1.10909125" defaultConfig { From 0afbece3b5b5551fc1735a79c72527ce2b565c33 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sat, 7 Sep 2024 15:53:11 -0400 Subject: [PATCH 2/3] .idea: Whatever updates Android Studio wants --- .idea/deploymentTargetSelector.xml | 10 ++++++++++ .idea/gradle.xml | 16 +++++++++++++--- .idea/migrations.xml | 10 ++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 .idea/deploymentTargetSelector.xml create mode 100644 .idea/migrations.xml diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..913d49d --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 163d6b4..589fc6c 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -4,11 +4,20 @@ diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file From c681e99e4762be890b81fb419b799aca3c935d12 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sat, 7 Sep 2024 16:02:28 -0400 Subject: [PATCH 3/3] refactor: lpac-jni: Move profiles linked list to Kotlin handling too --- .../java/net/typeblog/lpac_jni/LpacJni.kt | 12 +- .../impl/LocalProfileAssistantImpl.kt | 23 +++- .../lpac-jni/src/main/jni/lpac-jni/lpac-jni.c | 121 +++++------------- .../lpac-jni/src/main/jni/lpac-jni/lpac-jni.h | 8 +- .../main/jni/lpac-jni/lpac-notifications.c | 6 +- 5 files changed, 70 insertions(+), 100 deletions(-) diff --git a/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/LpacJni.kt b/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/LpacJni.kt index 37406a7..d4ea8b2 100644 --- a/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/LpacJni.kt +++ b/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/LpacJni.kt @@ -14,7 +14,7 @@ internal object LpacJni { // es10c // null returns signify errors external fun es10cGetEid(handle: Long): String? - external fun es10cGetProfilesInfo(handle: Long): Array? + external fun es10cGetProfilesInfo(handle: Long): Long external fun es10cEnableProfile(handle: Long, iccid: String, refresh: Boolean): Int external fun es10cDisableProfile(handle: Long, iccid: String, refresh: Boolean): Int external fun es10cDeleteProfile(handle: Long, iccid: String): Int @@ -34,6 +34,16 @@ internal object LpacJni { external fun es10cexGetEuiccInfo2(handle: Long): EuiccInfo2? // C <-> Java struct / linked list handling + // Profiles + external fun profilesNext(curr: Long): Long + external fun profilesFree(head: Long): Long + external fun profileGetIccid(curr: Long): String + external fun profileGetIsdpAid(curr: Long): String + external fun profileGetName(curr: Long): String + external fun profileGetNickname(curr: Long): String + external fun profileGetServiceProvider(curr: Long): String + external fun profileGetStateString(curr: Long): String + external fun profileGetClassString(curr: Long): String // Notifications external fun notificationsNext(curr: Long): Long external fun notificationGetSeq(curr: Long): Long diff --git a/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/impl/LocalProfileAssistantImpl.kt b/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/impl/LocalProfileAssistantImpl.kt index 0b03b64..4515ea6 100644 --- a/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/impl/LocalProfileAssistantImpl.kt +++ b/libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/impl/LocalProfileAssistantImpl.kt @@ -42,7 +42,28 @@ class LocalProfileAssistantImpl( } override val profiles: List - get() = LpacJni.es10cGetProfilesInfo(contextHandle)?.asList() ?: listOf() + get() { + val head = LpacJni.es10cGetProfilesInfo(contextHandle) + var curr = head + val ret = mutableListOf() + while (curr != 0L) { + val state = LocalProfileInfo.State.fromString(LpacJni.profileGetStateString(curr)) + val clazz = LocalProfileInfo.Clazz.fromString(LpacJni.profileGetClassString(curr)) + ret.add(LocalProfileInfo( + LpacJni.profileGetIccid(curr), + state, + LpacJni.profileGetName(curr), + LpacJni.profileGetNickname(curr), + LpacJni.profileGetServiceProvider(curr), + LpacJni.profileGetIsdpAid(curr), + clazz + )) + curr = LpacJni.profilesNext(curr) + } + + LpacJni.profilesFree(curr) + return ret + } override val notifications: List get() { diff --git a/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.c b/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.c index 561e027..5dcddce 100644 --- a/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.c +++ b/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.c @@ -12,15 +12,6 @@ JavaVM *jvm = NULL; -jclass local_profile_info_class; -jmethodID local_profile_info_constructor; - -jclass local_profile_state_class; -jmethodID local_profile_state_from_string; - -jclass local_profile_class_class; -jmethodID local_profile_class_from_string; - jstring empty_string; jclass string_class; @@ -40,25 +31,6 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) { string_constructor = (*env)->GetMethodID(env, string_class, "", "([BLjava/lang/String;)V"); - local_profile_info_class = (*env)->FindClass(env, "net/typeblog/lpac_jni/LocalProfileInfo"); - local_profile_info_class = (*env)->NewGlobalRef(env, local_profile_info_class); - local_profile_info_constructor = (*env)->GetMethodID(env, local_profile_info_class, "", - "(Ljava/lang/String;Lnet/typeblog/lpac_jni/LocalProfileInfo$State;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lnet/typeblog/lpac_jni/LocalProfileInfo$Clazz;)V"); - - local_profile_state_class = (*env)->FindClass(env, - "net/typeblog/lpac_jni/LocalProfileInfo$State"); - local_profile_state_class = (*env)->NewGlobalRef(env, local_profile_state_class); - local_profile_state_from_string = (*env)->GetStaticMethodID(env, local_profile_state_class, - "fromString", - "(Ljava/lang/String;)Lnet/typeblog/lpac_jni/LocalProfileInfo$State;"); - - local_profile_class_class = (*env)->FindClass(env, - "net/typeblog/lpac_jni/LocalProfileInfo$Clazz"); - local_profile_class_class = (*env)->NewGlobalRef(env, local_profile_class_class); - local_profile_class_from_string = (*env)->GetStaticMethodID(env, local_profile_class_class, - "fromString", - "(Ljava/lang/String;)Lnet/typeblog/lpac_jni/LocalProfileInfo$Clazz;"); - euicc_info2_class = (*env)->FindClass(env, "net/typeblog/lpac_jni/EuiccInfo2"); euicc_info2_class = (*env)->NewGlobalRef(env, euicc_info2_class); euicc_info2_constructor = (*env)->GetMethodID(env, euicc_info2_class, "", @@ -144,25 +116,23 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10cGetEid(JNIEnv *env, jobject thiz, jlong return ret; } -jobject profile_info_native_to_java(JNIEnv *env, struct es10c_profile_info_list *info) { +JNIEXPORT jlong JNICALL +Java_net_typeblog_lpac_1jni_LpacJni_es10cGetProfilesInfo(JNIEnv *env, jobject thiz, jlong handle) { + struct euicc_ctx *ctx = (struct euicc_ctx *) handle; + struct es10c_profile_info_list *info = NULL; + + if (es10c_get_profiles_info(ctx, &info) < 0) { + return 0; + } + + return (jlong) info; +} + +JNIEXPORT jstring JNICALL +Java_net_typeblog_lpac_1jni_LpacJni_profileGetStateString(JNIEnv *env, jobject thiz, jlong curr) { + struct es10c_profile_info_list *info = (struct es10c_profile_info_list *) curr; const char *profileStateStr = NULL; - const char *profileClassStr = NULL; - jstring serviceProvider = NULL; - jstring nickName = NULL; - jstring isdpAid = NULL; - jstring iccid = NULL; - jstring name = NULL; - jobject state = NULL; - jobject class = NULL; - jobject jinfo = NULL; - iccid = toJString(env, info->iccid); - isdpAid = toJString(env, info->isdpAid); - name = toJString(env, info->profileName); - nickName = toJString(env, info->profileNickname); - serviceProvider = toJString(env, info->serviceProviderName); - - // TODO: Maybe we should pass a Java object directly here? switch (info->profileState) { case ES10C_PROFILE_STATE_ENABLED: profileStateStr = "enabled"; @@ -174,9 +144,13 @@ jobject profile_info_native_to_java(JNIEnv *env, struct es10c_profile_info_list profileStateStr = "unknown"; } - state = (*env)->CallStaticObjectMethod(env, local_profile_state_class, - local_profile_state_from_string, - toJString(env, profileStateStr)); + return toJString(env, profileStateStr); +} + +JNIEXPORT jstring JNICALL +Java_net_typeblog_lpac_1jni_LpacJni_profileGetClassString(JNIEnv *env, jobject thiz, jlong curr) { + struct es10c_profile_info_list *info = (struct es10c_profile_info_list *) curr; + const char *profileClassStr = NULL; switch (info->profileClass) { case ES10C_PROFILE_CLASS_TEST: @@ -193,51 +167,16 @@ jobject profile_info_native_to_java(JNIEnv *env, struct es10c_profile_info_list break; } - class = (*env)->CallStaticObjectMethod(env, local_profile_class_class, - local_profile_class_from_string, - toJString(env, profileClassStr)); - - jinfo = (*env)->NewObject(env, local_profile_info_class, local_profile_info_constructor, - iccid, state, name, nickName, serviceProvider, isdpAid, class); - - (*env)->DeleteLocalRef(env, class); - (*env)->DeleteLocalRef(env, state); - (*env)->DeleteLocalRef(env, serviceProvider); - (*env)->DeleteLocalRef(env, nickName); - (*env)->DeleteLocalRef(env, name); - (*env)->DeleteLocalRef(env, isdpAid); - (*env)->DeleteLocalRef(env, iccid); - - return jinfo; + return toJString(env, profileClassStr); } -JNIEXPORT jobjectArray JNICALL -Java_net_typeblog_lpac_1jni_LpacJni_es10cGetProfilesInfo(JNIEnv *env, jobject thiz, jlong handle) { - struct euicc_ctx *ctx = (struct euicc_ctx *) handle; - struct es10c_profile_info_list *info = NULL; - struct es10c_profile_info_list *curr = NULL; - jobjectArray ret = NULL; - jobject jinfo = NULL; - int count = 0; - - if (es10c_get_profiles_info(ctx, &info) < 0) { - return NULL; - } - - count = LPAC_JNI_LINKED_LIST_COUNT(info, curr); - - ret = (*env)->NewObjectArray(env, count, local_profile_info_class, NULL); - - // Convert the native info array to Java - LPAC_JNI_LINKED_LIST_FOREACH(info, curr, { - jinfo = profile_info_native_to_java(env, curr); - (*env)->SetObjectArrayElement(env, ret, i, jinfo); - (*env)->DeleteLocalRef(env, jinfo); - }); - - es10c_profile_info_list_free_all(info); - return ret; -} +LPAC_JNI_STRUCT_GETTER_LINKED_LIST_NEXT(struct es10c_profile_info_list, profiles) +LPAC_JNI_STRUCT_LINKED_LIST_FREE(struct es10c_profile_info_list, profiles, es10c_profile_info_list_free_all) +LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_profile_info_list, profile, iccid, Iccid) +LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_profile_info_list, profile, isdpAid, IsdpAid) +LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_profile_info_list, profile, profileName, Name) +LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_profile_info_list, profile, profileNickname, Nickname) +LPAC_JNI_STRUCT_GETTER_STRING(struct es10c_profile_info_list, profile, serviceProviderName, ServiceProvider) JNIEXPORT jint JNICALL Java_net_typeblog_lpac_1jni_LpacJni_es10cEnableProfile(JNIEnv *env, jobject thiz, jlong handle, diff --git a/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.h b/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.h index 4d537ee..d185551 100644 --- a/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.h +++ b/libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.h @@ -66,15 +66,15 @@ jstring toJString(JNIEnv *env, const char *pat); free_func(p); \ } -#define LPAC_JNI_STRUCT_GETTER_LONG(st, name, jname) \ - JNIEXPORT jlong JNICALL Java_net_typeblog_lpac_1jni_LpacJni_notificationGet##jname(JNIEnv *env, jobject thiz, jlong raw) { \ +#define LPAC_JNI_STRUCT_GETTER_LONG(st, st_name, name, jname) \ + JNIEXPORT jlong JNICALL Java_net_typeblog_lpac_1jni_LpacJni_##st_name##Get##jname(JNIEnv *env, jobject thiz, jlong raw) { \ st *p = (st *) raw; \ if (p == NULL) return 0; \ return (jlong) p->name; \ } -#define LPAC_JNI_STRUCT_GETTER_STRING(st, name, jname) \ - JNIEXPORT jstring JNICALL Java_net_typeblog_lpac_1jni_LpacJni_notificationGet##jname(JNIEnv *env, jobject thiz, jlong raw) { \ +#define LPAC_JNI_STRUCT_GETTER_STRING(st, st_name, name, jname) \ + JNIEXPORT jstring JNICALL Java_net_typeblog_lpac_1jni_LpacJni_##st_name##Get##jname(JNIEnv *env, jobject thiz, jlong raw) { \ st *p = (st *) raw; \ return toJString(env, p->name); \ } \ No newline at end of file diff --git a/libs/lpac-jni/src/main/jni/lpac-jni/lpac-notifications.c b/libs/lpac-jni/src/main/jni/lpac-jni/lpac-notifications.c index bd4dffd..b2c4825 100644 --- a/libs/lpac-jni/src/main/jni/lpac-jni/lpac-notifications.c +++ b/libs/lpac-jni/src/main/jni/lpac-jni/lpac-notifications.c @@ -74,6 +74,6 @@ Java_net_typeblog_lpac_1jni_LpacJni_notificationGetOperationString(JNIEnv *env, LPAC_JNI_STRUCT_GETTER_LINKED_LIST_NEXT(struct es10b_notification_metadata_list, notifications) LPAC_JNI_STRUCT_LINKED_LIST_FREE(struct es10b_notification_metadata_list, notifications, es10b_notification_metadata_list_free_all) -LPAC_JNI_STRUCT_GETTER_LONG(struct es10b_notification_metadata_list, seqNumber, Seq) -LPAC_JNI_STRUCT_GETTER_STRING(struct es10b_notification_metadata_list, notificationAddress, Address) -LPAC_JNI_STRUCT_GETTER_STRING(struct es10b_notification_metadata_list, iccid, Iccid) \ No newline at end of file +LPAC_JNI_STRUCT_GETTER_LONG(struct es10b_notification_metadata_list, notification, seqNumber, Seq) +LPAC_JNI_STRUCT_GETTER_STRING(struct es10b_notification_metadata_list, notification, notificationAddress, Address) +LPAC_JNI_STRUCT_GETTER_STRING(struct es10b_notification_metadata_list, notification, iccid, Iccid)