Browse Source

refactor: lpac-jni: Move profiles linked list to Kotlin handling too

Peter Cai 1 year ago
parent
commit
c681e99e47

+ 11 - 1
libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/LpacJni.kt

@@ -14,7 +14,7 @@ internal object LpacJni {
     // es10c
     // es10c
     // null returns signify errors
     // null returns signify errors
     external fun es10cGetEid(handle: Long): String?
     external fun es10cGetEid(handle: Long): String?
-    external fun es10cGetProfilesInfo(handle: Long): Array<LocalProfileInfo>?
+    external fun es10cGetProfilesInfo(handle: Long): Long
     external fun es10cEnableProfile(handle: Long, iccid: String, refresh: Boolean): Int
     external fun es10cEnableProfile(handle: Long, iccid: String, refresh: Boolean): Int
     external fun es10cDisableProfile(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
     external fun es10cDeleteProfile(handle: Long, iccid: String): Int
@@ -34,6 +34,16 @@ internal object LpacJni {
     external fun es10cexGetEuiccInfo2(handle: Long): EuiccInfo2?
     external fun es10cexGetEuiccInfo2(handle: Long): EuiccInfo2?
 
 
     // C <-> Java struct / linked list handling
     // 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
     // Notifications
     external fun notificationsNext(curr: Long): Long
     external fun notificationsNext(curr: Long): Long
     external fun notificationGetSeq(curr: Long): Long
     external fun notificationGetSeq(curr: Long): Long

+ 22 - 1
libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/impl/LocalProfileAssistantImpl.kt

@@ -42,7 +42,28 @@ class LocalProfileAssistantImpl(
         }
         }
 
 
     override val profiles: List<LocalProfileInfo>
     override val profiles: List<LocalProfileInfo>
-        get() = LpacJni.es10cGetProfilesInfo(contextHandle)?.asList() ?: listOf()
+        get() {
+            val head = LpacJni.es10cGetProfilesInfo(contextHandle)
+            var curr = head
+            val ret = mutableListOf<LocalProfileInfo>()
+            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<LocalProfileNotification>
     override val notifications: List<LocalProfileNotification>
         get() {
         get() {

+ 31 - 92
libs/lpac-jni/src/main/jni/lpac-jni/lpac-jni.c

@@ -12,15 +12,6 @@
 
 
 JavaVM *jvm = NULL;
 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;
 jstring empty_string;
 
 
 jclass string_class;
 jclass string_class;
@@ -40,25 +31,6 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) {
     string_constructor = (*env)->GetMethodID(env, string_class, "<init>",
     string_constructor = (*env)->GetMethodID(env, string_class, "<init>",
                                              "([BLjava/lang/String;)V");
                                              "([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, "<init>",
-                                                         "(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)->FindClass(env, "net/typeblog/lpac_jni/EuiccInfo2");
     euicc_info2_class = (*env)->NewGlobalRef(env, euicc_info2_class);
     euicc_info2_class = (*env)->NewGlobalRef(env, euicc_info2_class);
     euicc_info2_constructor = (*env)->GetMethodID(env, euicc_info2_class, "<init>",
     euicc_info2_constructor = (*env)->GetMethodID(env, euicc_info2_class, "<init>",
@@ -144,25 +116,23 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10cGetEid(JNIEnv *env, jobject thiz, jlong
     return ret;
     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 *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) {
     switch (info->profileState) {
         case ES10C_PROFILE_STATE_ENABLED:
         case ES10C_PROFILE_STATE_ENABLED:
             profileStateStr = "enabled";
             profileStateStr = "enabled";
@@ -174,9 +144,13 @@ jobject profile_info_native_to_java(JNIEnv *env, struct es10c_profile_info_list
             profileStateStr = "unknown";
             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) {
     switch (info->profileClass) {
         case ES10C_PROFILE_CLASS_TEST:
         case ES10C_PROFILE_CLASS_TEST:
@@ -193,51 +167,16 @@ jobject profile_info_native_to_java(JNIEnv *env, struct es10c_profile_info_list
             break;
             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
 JNIEXPORT jint JNICALL
 Java_net_typeblog_lpac_1jni_LpacJni_es10cEnableProfile(JNIEnv *env, jobject thiz, jlong handle,
 Java_net_typeblog_lpac_1jni_LpacJni_es10cEnableProfile(JNIEnv *env, jobject thiz, jlong handle,

+ 4 - 4
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);                             \
             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;                       \
             st *p = (st *) raw;                       \
             if (p == NULL) return 0;                  \
             if (p == NULL) return 0;                  \
             return (jlong) p->name;                   \
             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;                       \
             st *p = (st *) raw;                       \
             return toJString(env, p->name);           \
             return toJString(env, p->name);           \
         }
         }

+ 3 - 3
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_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_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)
+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)