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 ce09717..3674f4f 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 @@ -11,14 +11,12 @@ import net.typeblog.lpac_jni.LocalProfileInfo import net.typeblog.lpac_jni.LocalProfileNotification import net.typeblog.lpac_jni.ProfileDownloadCallback import net.typeblog.lpac_jni.Version -import java.util.concurrent.locks.ReentrantLock -import kotlin.concurrent.withLock class LocalProfileAssistantImpl( isdrAid: ByteArray, rawApduInterface: ApduInterface, rawHttpInterface: HttpInterface -) : LocalProfileAssistant { +): LocalProfileAssistant { companion object { private const val TAG = "LocalProfileAssistantImpl" } @@ -76,10 +74,6 @@ class LocalProfileAssistantImpl( } } - // Controls concurrency of every single method in this class, since - // the C-side is explicitly NOT thread-safe - private val lock = ReentrantLock() - private val apduInterface = ApduInterfaceWrapper(rawApduInterface) private val httpInterface = HttpInterfaceWrapper(rawHttpInterface) @@ -111,24 +105,23 @@ class LocalProfileAssistantImpl( } override val profiles: List - get() = lock.withLock { + @Synchronized + 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 - ) - ) + ret.add(LocalProfileInfo( + LpacJni.profileGetIccid(curr), + state, + LpacJni.profileGetName(curr), + LpacJni.profileGetNickname(curr), + LpacJni.profileGetServiceProvider(curr), + LpacJni.profileGetIsdpAid(curr), + clazz + )) curr = LpacJni.profilesNext(curr) } @@ -137,87 +130,79 @@ class LocalProfileAssistantImpl( } override val notifications: List - get() = lock.withLock { + @Synchronized + get() { val head = LpacJni.es10bListNotification(contextHandle) var curr = head - - try { - val ret = mutableListOf() - while (curr != 0L) { - ret.add( - LocalProfileNotification( - LpacJni.notificationGetSeq(curr), - LocalProfileNotification.Operation.fromString( - LpacJni.notificationGetOperationString( - curr - ) - ), - LpacJni.notificationGetAddress(curr), - LpacJni.notificationGetIccid(curr), - ) - ) - curr = LpacJni.notificationsNext(curr) - } - return ret.sortedBy { it.seqNumber }.reversed() - } finally { - LpacJni.notificationsFree(head) + val ret = mutableListOf() + while (curr != 0L) { + 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 - get() = lock.withLock { LpacJni.es10cGetEid(contextHandle)!! } + @Synchronized + get() = LpacJni.es10cGetEid(contextHandle)!! override val euiccInfo2: EuiccInfo2? - get() = lock.withLock { + @Synchronized + get() { val cInfo = LpacJni.es10cexGetEuiccInfo2(contextHandle) if (cInfo == 0L) return null - try { - return EuiccInfo2( - Version(LpacJni.euiccInfo2GetSGP22Version(cInfo)), - Version(LpacJni.euiccInfo2GetProfileVersion(cInfo)), - Version(LpacJni.euiccInfo2GetEuiccFirmwareVersion(cInfo)), - Version(LpacJni.euiccInfo2GetGlobalPlatformVersion(cInfo)), - LpacJni.euiccInfo2GetSasAcreditationNumber(cInfo), - Version(LpacJni.euiccInfo2GetPpVersion(cInfo)), - LpacJni.euiccInfo2GetFreeNonVolatileMemory(cInfo).toInt(), - LpacJni.euiccInfo2GetFreeVolatileMemory(cInfo).toInt(), - buildSet { - var cursor = LpacJni.euiccInfo2GetEuiccCiPKIdListForSigning(cInfo) - while (cursor != 0L) { - add(LpacJni.stringDeref(cursor)) - cursor = LpacJni.stringArrNext(cursor) - } - }, - buildSet { - var cursor = LpacJni.euiccInfo2GetEuiccCiPKIdListForVerification(cInfo) - while (cursor != 0L) { - add(LpacJni.stringDeref(cursor)) - cursor = LpacJni.stringArrNext(cursor) - } - }, - ) - } finally { - LpacJni.euiccInfo2Free(cInfo) - } + val ret = EuiccInfo2( + Version(LpacJni.euiccInfo2GetSGP22Version(cInfo)), + Version(LpacJni.euiccInfo2GetProfileVersion(cInfo)), + Version(LpacJni.euiccInfo2GetEuiccFirmwareVersion(cInfo)), + Version(LpacJni.euiccInfo2GetGlobalPlatformVersion(cInfo)), + LpacJni.euiccInfo2GetSasAcreditationNumber(cInfo), + Version(LpacJni.euiccInfo2GetPpVersion(cInfo)), + LpacJni.euiccInfo2GetFreeNonVolatileMemory(cInfo).toInt(), + LpacJni.euiccInfo2GetFreeVolatileMemory(cInfo).toInt(), + buildSet { + var cursor = LpacJni.euiccInfo2GetEuiccCiPKIdListForSigning(cInfo) + while (cursor != 0L) { + add(LpacJni.stringDeref(cursor)) + cursor = LpacJni.stringArrNext(cursor) + } + }, + buildSet { + var cursor = LpacJni.euiccInfo2GetEuiccCiPKIdListForVerification(cInfo) + while (cursor != 0L) { + add(LpacJni.stringDeref(cursor)) + cursor = LpacJni.stringArrNext(cursor) + } + }, + ) + + LpacJni.euiccInfo2Free(cInfo) + + return ret } - override fun enableProfile(iccid: String, refresh: Boolean): Boolean = lock.withLock { + @Synchronized + override fun enableProfile(iccid: String, refresh: Boolean): Boolean = LpacJni.es10cEnableProfile(contextHandle, iccid, refresh) == 0 - } - override fun disableProfile(iccid: String, refresh: Boolean): Boolean = lock.withLock { + @Synchronized + override fun disableProfile(iccid: String, refresh: Boolean): Boolean = LpacJni.es10cDisableProfile(contextHandle, iccid, refresh) == 0 - } - override fun deleteProfile(iccid: String): Boolean = lock.withLock { + @Synchronized + override fun deleteProfile(iccid: String): Boolean = LpacJni.es10cDeleteProfile(contextHandle, iccid) == 0 - } - override fun downloadProfile( - smdp: String, matchingId: String?, imei: String?, - confirmationCode: String?, callback: ProfileDownloadCallback - ) = lock.withLock { + @Synchronized + override fun downloadProfile(smdp: String, matchingId: String?, imei: String?, + confirmationCode: String?, callback: ProfileDownloadCallback) { val res = LpacJni.downloadProfile( contextHandle, smdp, @@ -244,17 +229,18 @@ class LocalProfileAssistantImpl( } } - override fun deleteNotification(seqNumber: Long): Boolean = lock.withLock { + @Synchronized + override fun deleteNotification(seqNumber: Long): Boolean = LpacJni.es10bDeleteNotification(contextHandle, seqNumber) == 0 - } - override fun handleNotification(seqNumber: Long): Boolean = lock.withLock { + @Synchronized + override fun handleNotification(seqNumber: Long): Boolean = LpacJni.handleNotification(contextHandle, seqNumber).also { Log.d(TAG, "handleNotification $seqNumber = $it") } == 0 - } - override fun setNickname(iccid: String, nickname: String) = lock.withLock { + @Synchronized + override fun setNickname(iccid: String, nickname: String) { val encoded = try { Charsets.UTF_8.encode(nickname).array() } catch (e: CharacterCodingException) { @@ -273,12 +259,11 @@ class LocalProfileAssistantImpl( } override fun euiccMemoryReset() { - lock.withLock { - LpacJni.es10cEuiccMemoryReset(contextHandle) - } + LpacJni.es10cEuiccMemoryReset(contextHandle) } - override fun close() = lock.withLock { + @Synchronized + override fun close() { if (!finalized) { LpacJni.euiccFini(contextHandle) LpacJni.destroyContext(contextHandle)