Compare commits
1 commit
5d22fb5b2a
...
a56c2b6d89
Author | SHA1 | Date | |
---|---|---|---|
a56c2b6d89 |
7 changed files with 126 additions and 89 deletions
|
@ -26,6 +26,7 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import net.typeblog.lpac_jni.LocalProfileNotification
|
import net.typeblog.lpac_jni.LocalProfileNotification
|
||||||
|
import net.typeblog.lpac_jni.ProfileManagementOperation
|
||||||
|
|
||||||
class NotificationsActivity: BaseEuiccAccessActivity(), OpenEuiccContextMarker {
|
class NotificationsActivity: BaseEuiccAccessActivity(), OpenEuiccContextMarker {
|
||||||
private lateinit var swipeRefresh: SwipeRefreshLayout
|
private lateinit var swipeRefresh: SwipeRefreshLayout
|
||||||
|
@ -163,13 +164,13 @@ class NotificationsActivity: BaseEuiccAccessActivity(), OpenEuiccContextMarker {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun operationToLocalizedText(operation: LocalProfileNotification.Operation) =
|
private fun operationToLocalizedText(operation: ProfileManagementOperation) =
|
||||||
root.context.getText(
|
root.context.getText(when (operation) {
|
||||||
when (operation) {
|
ProfileManagementOperation.Install -> R.string.profile_notification_operation_download
|
||||||
LocalProfileNotification.Operation.Install -> R.string.profile_notification_operation_download
|
ProfileManagementOperation.Delete -> R.string.profile_notification_operation_delete
|
||||||
LocalProfileNotification.Operation.Delete -> R.string.profile_notification_operation_delete
|
ProfileManagementOperation.Enable -> R.string.profile_notification_operation_enable
|
||||||
LocalProfileNotification.Operation.Enable -> R.string.profile_notification_operation_enable
|
ProfileManagementOperation.Disable -> R.string.profile_notification_operation_disable
|
||||||
LocalProfileNotification.Operation.Disable -> R.string.profile_notification_operation_disable
|
else -> throw IllegalStateException("Unknown operation")
|
||||||
})
|
})
|
||||||
|
|
||||||
fun updateNotification(value: LocalProfileNotificationWrapper) {
|
fun updateNotification(value: LocalProfileNotificationWrapper) {
|
||||||
|
|
|
@ -2,26 +2,15 @@ package net.typeblog.lpac_jni
|
||||||
|
|
||||||
data class LocalProfileNotification(
|
data class LocalProfileNotification(
|
||||||
val seqNumber: Long,
|
val seqNumber: Long,
|
||||||
val profileManagementOperation: Operation,
|
val profileManagementOperation: ProfileManagementOperation,
|
||||||
val notificationAddress: String,
|
val notificationAddress: String,
|
||||||
val iccid: String,
|
val iccid: String,
|
||||||
) {
|
)
|
||||||
enum class Operation {
|
|
||||||
|
enum class ProfileManagementOperation {
|
||||||
Install,
|
Install,
|
||||||
Enable,
|
Enable,
|
||||||
Disable,
|
Disable,
|
||||||
Delete;
|
Delete,
|
||||||
|
Unknown,
|
||||||
companion object {
|
|
||||||
@JvmStatic
|
|
||||||
fun fromString(str: String?) =
|
|
||||||
when (str?.lowercase()) {
|
|
||||||
"install" -> Install
|
|
||||||
"enable" -> Enable
|
|
||||||
"disable" -> Disable
|
|
||||||
"delete" -> Delete
|
|
||||||
else -> throw IllegalArgumentException("Unknown operation $str")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -26,7 +26,7 @@ internal object LpacJni {
|
||||||
external fun es10cSetNickname(handle: Long, iccid: String, nickNullTerminated: ByteArray): Int
|
external fun es10cSetNickname(handle: Long, iccid: String, nickNullTerminated: ByteArray): Int
|
||||||
|
|
||||||
// es10b
|
// es10b
|
||||||
external fun es10bListNotification(handle: Long): Long // A native pointer to a linked list. Handle with linked list-related methods below. May be 0 (null)
|
external fun es10bListNotification(handle: Long, elements: List<LocalProfileNotification>): Int
|
||||||
external fun es10bDeleteNotification(handle: Long, seqNumber: Long): Int
|
external fun es10bDeleteNotification(handle: Long, seqNumber: Long): Int
|
||||||
|
|
||||||
// es9p + es10b
|
// es9p + es10b
|
||||||
|
@ -57,13 +57,6 @@ internal object LpacJni {
|
||||||
external fun profileGetServiceProvider(curr: Long): String
|
external fun profileGetServiceProvider(curr: Long): String
|
||||||
external fun profileGetStateString(curr: Long): String
|
external fun profileGetStateString(curr: Long): String
|
||||||
external fun profileGetClassString(curr: Long): String
|
external fun profileGetClassString(curr: Long): String
|
||||||
// Notifications
|
|
||||||
external fun notificationsNext(curr: Long): Long
|
|
||||||
external fun notificationGetSeq(curr: Long): Long
|
|
||||||
external fun notificationGetOperationString(curr: Long): String
|
|
||||||
external fun notificationGetAddress(curr: Long): String
|
|
||||||
external fun notificationGetIccid(curr: Long): String
|
|
||||||
external fun notificationsFree(head: Long)
|
|
||||||
// EuiccInfo2
|
// EuiccInfo2
|
||||||
external fun euiccInfo2Free(info: Long)
|
external fun euiccInfo2Free(info: Long)
|
||||||
external fun euiccInfo2GetSGP22Version(info: Long): String
|
external fun euiccInfo2GetSGP22Version(info: Long): String
|
||||||
|
|
|
@ -132,20 +132,10 @@ class LocalProfileAssistantImpl(
|
||||||
override val notifications: List<LocalProfileNotification>
|
override val notifications: List<LocalProfileNotification>
|
||||||
@Synchronized
|
@Synchronized
|
||||||
get() {
|
get() {
|
||||||
val head = LpacJni.es10bListNotification(contextHandle)
|
val notifications = mutableListOf<LocalProfileNotification>()
|
||||||
var curr = head
|
val ret = LpacJni.es10bListNotification(contextHandle, notifications)
|
||||||
val ret = mutableListOf<LocalProfileNotification>()
|
if (ret < 0) throw IllegalStateException("Failed to list notifications")
|
||||||
while (curr != 0L) {
|
return notifications.sortedBy(LocalProfileNotification::seqNumber).reversed()
|
||||||
ret.add(LocalProfileNotification(
|
|
||||||
LpacJni.notificationGetSeq(curr),
|
|
||||||
LocalProfileNotification.Operation.fromString(LpacJni.notificationGetOperationString(curr)),
|
|
||||||
LpacJni.notificationGetAddress(curr),
|
|
||||||
LpacJni.notificationGetIccid(curr),
|
|
||||||
))
|
|
||||||
curr = LpacJni.notificationsNext(curr)
|
|
||||||
}
|
|
||||||
LpacJni.notificationsFree(head)
|
|
||||||
return ret.sortedBy { it.seqNumber }.reversed()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override val eID: String
|
override val eID: String
|
||||||
|
|
|
@ -19,10 +19,12 @@ jmethodID string_constructor;
|
||||||
|
|
||||||
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
|
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||||
jvm = vm;
|
jvm = vm;
|
||||||
|
LPAC_JNI_SETUP_ENV;
|
||||||
|
|
||||||
interface_wrapper_init();
|
interface_wrapper_init();
|
||||||
lpac_download_init();
|
lpac_download_init();
|
||||||
|
lpac_notifications_init(env);
|
||||||
|
|
||||||
LPAC_JNI_SETUP_ENV;
|
|
||||||
string_class = (*env)->FindClass(env, "java/lang/String");
|
string_class = (*env)->FindClass(env, "java/lang/String");
|
||||||
string_class = (*env)->NewGlobalRef(env, string_class);
|
string_class = (*env)->NewGlobalRef(env, string_class);
|
||||||
string_constructor = (*env)->GetMethodID(env, string_class, "<init>",
|
string_constructor = (*env)->GetMethodID(env, string_class, "<init>",
|
||||||
|
|
|
@ -4,15 +4,107 @@
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
|
||||||
JNIEXPORT jlong JNICALL
|
jclass local_profile_notification_class;
|
||||||
Java_net_typeblog_lpac_1jni_LpacJni_es10bListNotification(JNIEnv *env, jobject thiz, jlong handle) {
|
|
||||||
|
jobject profile_management_operation_install;
|
||||||
|
jobject profile_management_operation_enable;
|
||||||
|
jobject profile_management_operation_disable;
|
||||||
|
jobject profile_management_operation_delete;
|
||||||
|
jobject profile_management_operation_unknown;
|
||||||
|
|
||||||
|
jmethodID local_profile_notification_constructor;
|
||||||
|
|
||||||
|
#define LOCAL_PROFILE_NOTIFICATION_CLASS "net/typeblog/lpac_jni/LocalProfileNotification"
|
||||||
|
#define PROFILE_MANAGEMENT_OPERATION_CLASS "net/typeblog/lpac_jni/ProfileManagementOperation"
|
||||||
|
|
||||||
|
static jobject bind_static_field(JNIEnv *env, jclass clazz, const char *name, const char *sig) {
|
||||||
|
jfieldID field = (*env)->GetStaticFieldID(env, clazz, name, sig);
|
||||||
|
jobject bound = (*env)->GetStaticObjectField(env, clazz, field);
|
||||||
|
return (*env)->NewGlobalRef(env, bound);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BIND_NOTIFICATION_OPERATION_FIELD(NAME, FIELD) \
|
||||||
|
profile_management_operation_##NAME = bind_static_field( \
|
||||||
|
env, profile_management_operation_class, FIELD, "L" PROFILE_MANAGEMENT_OPERATION_CLASS ";")
|
||||||
|
|
||||||
|
void lpac_notifications_init(JNIEnv *env) {
|
||||||
|
local_profile_notification_class = (*env)->FindClass(env, LOCAL_PROFILE_NOTIFICATION_CLASS);
|
||||||
|
local_profile_notification_class = (*env)->NewGlobalRef(env, local_profile_notification_class);
|
||||||
|
local_profile_notification_constructor = (*env)->GetMethodID(
|
||||||
|
env, local_profile_notification_class, "<init>",
|
||||||
|
"("
|
||||||
|
"J" // seqNumber
|
||||||
|
"L" PROFILE_MANAGEMENT_OPERATION_CLASS ";" // profileManagementOperation
|
||||||
|
"Ljava/lang/String;" // notificationAddress
|
||||||
|
"Ljava/lang/String;" // iccid
|
||||||
|
")"
|
||||||
|
"V" // (returns) void
|
||||||
|
);
|
||||||
|
|
||||||
|
jclass profile_management_operation_class = (*env)->FindClass(
|
||||||
|
env, PROFILE_MANAGEMENT_OPERATION_CLASS);
|
||||||
|
profile_management_operation_class = (*env)->NewGlobalRef(
|
||||||
|
env, profile_management_operation_class);
|
||||||
|
|
||||||
|
BIND_NOTIFICATION_OPERATION_FIELD(install, "Install");
|
||||||
|
BIND_NOTIFICATION_OPERATION_FIELD(delete, "Delete");
|
||||||
|
BIND_NOTIFICATION_OPERATION_FIELD(enable, "Enable");
|
||||||
|
BIND_NOTIFICATION_OPERATION_FIELD(disable, "Disable");
|
||||||
|
BIND_NOTIFICATION_OPERATION_FIELD(unknown, "Unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef BIND_NOTIFICATION_OPERATION_FIELD
|
||||||
|
|
||||||
|
static jobject to_profile_management_operation(enum es10b_profile_management_operation operation) {
|
||||||
|
switch (operation) {
|
||||||
|
case ES10B_PROFILE_MANAGEMENT_OPERATION_INSTALL:
|
||||||
|
return profile_management_operation_install;
|
||||||
|
case ES10B_PROFILE_MANAGEMENT_OPERATION_DELETE:
|
||||||
|
return profile_management_operation_delete;
|
||||||
|
case ES10B_PROFILE_MANAGEMENT_OPERATION_ENABLE:
|
||||||
|
return profile_management_operation_enable;
|
||||||
|
case ES10B_PROFILE_MANAGEMENT_OPERATION_DISABLE:
|
||||||
|
return profile_management_operation_disable;
|
||||||
|
default:
|
||||||
|
return profile_management_operation_unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_net_typeblog_lpac_1jni_LpacJni_es10bListNotification(
|
||||||
|
JNIEnv *env,
|
||||||
|
__attribute__((unused)) jobject thiz,
|
||||||
|
jlong handle,
|
||||||
|
jobject notifications
|
||||||
|
) {
|
||||||
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
|
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
|
||||||
struct es10b_notification_metadata_list *info = NULL;
|
struct es10b_notification_metadata_list *metadata = NULL;
|
||||||
|
int ret = es10b_list_notification(ctx, &metadata);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (es10b_list_notification(ctx, &info) < 0)
|
jmethodID add_notification = (*env)->GetMethodID(
|
||||||
return 0;
|
env,
|
||||||
|
(*env)->GetObjectClass(env, notifications),
|
||||||
|
"add", "(Ljava/lang/Object;)Z"
|
||||||
|
);
|
||||||
|
|
||||||
return (jlong) info;
|
jobject element;
|
||||||
|
while (metadata) {
|
||||||
|
jlong sequence_number = metadata->seqNumber;
|
||||||
|
jobject operation = to_profile_management_operation(metadata->profileManagementOperation);
|
||||||
|
jstring address = toJString(env, metadata->notificationAddress);
|
||||||
|
jstring iccid = toJString(env, metadata->iccid);
|
||||||
|
element = (*env)->NewObject(
|
||||||
|
env, local_profile_notification_class, local_profile_notification_constructor,
|
||||||
|
sequence_number, operation, address, iccid);
|
||||||
|
(*env)->CallBooleanMethod(env, notifications, add_notification, element);
|
||||||
|
metadata = metadata->next;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
es10b_notification_metadata_list_free_all(metadata);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
|
@ -45,35 +137,3 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10bDeleteNotification(JNIEnv *env, jobject
|
||||||
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
|
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
|
||||||
return es10b_remove_notification_from_list(ctx, (unsigned long) seq_number);
|
return es10b_remove_notification_from_list(ctx, (unsigned long) seq_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL
|
|
||||||
Java_net_typeblog_lpac_1jni_LpacJni_notificationGetOperationString(JNIEnv *env, jobject thiz,
|
|
||||||
jlong curr) {
|
|
||||||
struct es10b_notification_metadata_list *info = (struct es10b_notification_metadata_list *) curr;
|
|
||||||
const char *profileManagementOperationStr = NULL;
|
|
||||||
switch (info->profileManagementOperation) {
|
|
||||||
case ES10B_PROFILE_MANAGEMENT_OPERATION_INSTALL:
|
|
||||||
profileManagementOperationStr = "install";
|
|
||||||
break;
|
|
||||||
case ES10B_PROFILE_MANAGEMENT_OPERATION_DELETE:
|
|
||||||
profileManagementOperationStr = "delete";
|
|
||||||
break;
|
|
||||||
case ES10B_PROFILE_MANAGEMENT_OPERATION_ENABLE:
|
|
||||||
profileManagementOperationStr = "enable";
|
|
||||||
break;
|
|
||||||
case ES10B_PROFILE_MANAGEMENT_OPERATION_DISABLE:
|
|
||||||
profileManagementOperationStr = "disable";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
profileManagementOperationStr = "unknown";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return toJString(env, profileManagementOperationStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
LPAC_JNI_STRUCT_GETTER_LINKED_LIST_NEXT(struct es10b_notification_metadata_list, notifications)
|
|
||||||
LPAC_JNI_STRUCT_FREE(struct es10b_notification_metadata_list, notifications, es10b_notification_metadata_list_free_all)
|
|
||||||
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)
|
|
||||||
|
|
|
@ -2,3 +2,5 @@
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include "lpac-jni.h"
|
#include "lpac-jni.h"
|
||||||
|
|
||||||
|
void lpac_notifications_init(JNIEnv *env);
|
||||||
|
|
Loading…
Add table
Reference in a new issue