refactor: Emit structured profile info from the LPA library
This commit is contained in:
parent
5894dc9a71
commit
4b29660ef2
|
@ -14,6 +14,7 @@ import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.truphone.lpa.LocalProfileInfo
|
||||||
import com.truphone.lpa.impl.ProfileKey.*
|
import com.truphone.lpa.impl.ProfileKey.*
|
||||||
import com.truphone.lpad.progress.Progress
|
import com.truphone.lpad.progress.Progress
|
||||||
import im.angry.openeuicc.R
|
import im.angry.openeuicc.R
|
||||||
|
@ -78,7 +79,7 @@ class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfilesCh
|
||||||
}
|
}
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
adapter.profiles = profiles.filter { it[PROFILE_CLASS.name] != "0" }
|
adapter.profiles = profiles.filter { it.profileClass != LocalProfileInfo.Clazz.Testing }
|
||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
binding.swipeRefresh.isRefreshing = false
|
binding.swipeRefresh.isRefreshing = false
|
||||||
}
|
}
|
||||||
|
@ -134,9 +135,9 @@ class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfilesCh
|
||||||
binding.profileMenu.setOnClickListener { showOptionsMenu() }
|
binding.profileMenu.setOnClickListener { showOptionsMenu() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var profile: Map<String, String>
|
private lateinit var profile: LocalProfileInfo
|
||||||
|
|
||||||
fun setProfile(profile: Map<String, String>) {
|
fun setProfile(profile: LocalProfileInfo) {
|
||||||
this.profile = profile
|
this.profile = profile
|
||||||
binding.name.text = getName()
|
binding.name.text = getName()
|
||||||
|
|
||||||
|
@ -147,20 +148,18 @@ class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfilesCh
|
||||||
R.string.disabled
|
R.string.disabled
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
binding.provider.text = profile[PROVIDER_NAME.name]
|
binding.provider.text = profile.providerName
|
||||||
binding.iccid.text = profile[ICCID_LITTLE.name]!!
|
binding.iccid.text = profile.iccidLittleEndian
|
||||||
binding.iccid.transformationMethod = PasswordTransformationMethod.getInstance()
|
binding.iccid.transformationMethod = PasswordTransformationMethod.getInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isEnabled(): Boolean =
|
private fun isEnabled(): Boolean =
|
||||||
profile[STATE.name]?.lowercase() == "enabled"
|
profile.state == LocalProfileInfo.State.Enabled
|
||||||
|
|
||||||
private fun getName(): String =
|
private fun getName(): String =
|
||||||
if (profile[NICKNAME.name].isNullOrEmpty()) {
|
profile.nickName.ifEmpty {
|
||||||
profile[NAME.name]
|
profile.name
|
||||||
} else {
|
}
|
||||||
profile[NICKNAME.name]
|
|
||||||
}!!
|
|
||||||
|
|
||||||
private fun showOptionsMenu() {
|
private fun showOptionsMenu() {
|
||||||
PopupMenu(binding.root.context, binding.profileMenu).apply {
|
PopupMenu(binding.root.context, binding.profileMenu).apply {
|
||||||
|
@ -179,20 +178,20 @@ class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfilesCh
|
||||||
private fun onMenuItemClicked(item: MenuItem): Boolean =
|
private fun onMenuItemClicked(item: MenuItem): Boolean =
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.enable -> {
|
R.id.enable -> {
|
||||||
enableOrDisableProfile(profile[ICCID.name]!!, true)
|
enableOrDisableProfile(profile.iccid, true)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.disable -> {
|
R.id.disable -> {
|
||||||
enableOrDisableProfile(profile[ICCID.name]!!, false)
|
enableOrDisableProfile(profile.iccid, false)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.rename -> {
|
R.id.rename -> {
|
||||||
ProfileRenameFragment.newInstance(slotId, profile[ICCID.name]!!, getName())
|
ProfileRenameFragment.newInstance(slotId, profile.iccid, getName())
|
||||||
.show(childFragmentManager, ProfileRenameFragment.TAG)
|
.show(childFragmentManager, ProfileRenameFragment.TAG)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.delete -> {
|
R.id.delete -> {
|
||||||
ProfileDeleteFragment.newInstance(slotId, profile[ICCID.name]!!, getName())
|
ProfileDeleteFragment.newInstance(slotId, profile.iccid, getName())
|
||||||
.show(childFragmentManager, ProfileDeleteFragment.TAG)
|
.show(childFragmentManager, ProfileDeleteFragment.TAG)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -200,7 +199,7 @@ class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfilesCh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class EuiccProfileAdapter(var profiles: List<Map<String, String>>) : RecyclerView.Adapter<ViewHolder>() {
|
inner class EuiccProfileAdapter(var profiles: List<LocalProfileInfo>) : RecyclerView.Adapter<ViewHolder>() {
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
val binding =
|
val binding =
|
||||||
EuiccProfileBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
EuiccProfileBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
|
|
|
@ -3,6 +3,7 @@ plugins {
|
||||||
id 'com.android.application' version '7.1.3' apply false
|
id 'com.android.application' version '7.1.3' apply false
|
||||||
id 'com.android.library' version '7.1.3' apply false
|
id 'com.android.library' version '7.1.3' apply false
|
||||||
id 'org.jetbrains.kotlin.android' version '1.5.30' apply false
|
id 'org.jetbrains.kotlin.android' version '1.5.30' apply false
|
||||||
|
id 'org.jetbrains.kotlin.multiplatform' version '1.6.21' apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
task clean(type: Delete) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'kotlin'
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
tool
|
tool
|
||||||
|
@ -27,6 +28,7 @@ task genAsn1(type: JavaExec) {
|
||||||
}
|
}
|
||||||
|
|
||||||
compileJava.dependsOn genAsn1
|
compileJava.dependsOn genAsn1
|
||||||
|
compileKotlin.dependsOn genAsn1
|
||||||
|
|
||||||
description = 'LPAd SM-DP+ Connector'
|
description = 'LPAd SM-DP+ Connector'
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ public interface LocalProfileAssistant {
|
||||||
|
|
||||||
void downloadProfile(String matchingId, DownloadProgress progress) throws Exception;
|
void downloadProfile(String matchingId, DownloadProgress progress) throws Exception;
|
||||||
|
|
||||||
List<Map<String, String>> getProfiles();
|
List<LocalProfileInfo> getProfiles();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the EID from the eUICC
|
* Gets the EID from the eUICC
|
||||||
|
@ -38,5 +38,6 @@ public interface LocalProfileAssistant {
|
||||||
|
|
||||||
void processPendingNotifications();
|
void processPendingNotifications();
|
||||||
|
|
||||||
boolean setNickname(String iccid, String nickname);
|
boolean setNickname(String iccid, String nickname
|
||||||
|
);
|
||||||
}
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 Peter Cai & Pierre-Hugues Husson
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program.
|
||||||
|
* If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.truphone.lpa
|
||||||
|
|
||||||
|
import java.lang.IllegalArgumentException
|
||||||
|
import java.lang.StringBuilder
|
||||||
|
|
||||||
|
data class LocalProfileInfo(
|
||||||
|
val iccid: String,
|
||||||
|
val state: State,
|
||||||
|
val name: String,
|
||||||
|
val nickName: String,
|
||||||
|
val providerName: String,
|
||||||
|
val isdpAID: String,
|
||||||
|
val profileClass: Clazz
|
||||||
|
) {
|
||||||
|
val iccidLittleEndian by lazy {
|
||||||
|
iccidBigToLittle(iccid)
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class State {
|
||||||
|
Enabled,
|
||||||
|
Disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class Clazz {
|
||||||
|
Testing,
|
||||||
|
Provisioning,
|
||||||
|
Operational
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun stateFromString(state: String?): State =
|
||||||
|
if (state == "0") {
|
||||||
|
State.Disabled
|
||||||
|
} else {
|
||||||
|
State.Enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
fun classFromString(clazz: String?): Clazz =
|
||||||
|
when (clazz) {
|
||||||
|
"0" -> Clazz.Testing
|
||||||
|
"1" -> Clazz.Provisioning
|
||||||
|
"2" -> Clazz.Operational
|
||||||
|
else -> throw IllegalArgumentException("Unknown profile class $clazz")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun iccidBigToLittle(iccid: String): String {
|
||||||
|
val builder = StringBuilder()
|
||||||
|
for (i in 0 until iccid.length / 2) {
|
||||||
|
builder.append(iccid[i * 2 + 1])
|
||||||
|
if (iccid[i * 2] != 'F') builder.append(iccid[i * 2])
|
||||||
|
}
|
||||||
|
return builder.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,107 +0,0 @@
|
||||||
package com.truphone.lpa.impl;
|
|
||||||
|
|
||||||
import com.truphone.rsp.dto.asn1.rspdefinitions.ProfileInfo;
|
|
||||||
import com.truphone.rsp.dto.asn1.rspdefinitions.ProfileInfoListResponse;
|
|
||||||
import org.apache.commons.codec.DecoderException;
|
|
||||||
import org.apache.commons.codec.binary.Hex;
|
|
||||||
import com.truphone.lpa.ApduChannel;
|
|
||||||
import com.truphone.lpa.apdu.ApduUtils;
|
|
||||||
import com.truphone.util.LogStub;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
class ListProfilesWorker {
|
|
||||||
private static final Logger LOG = Logger.getLogger(ListProfilesWorker.class.getName());
|
|
||||||
|
|
||||||
private final ApduChannel apduChannel;
|
|
||||||
|
|
||||||
ListProfilesWorker(ApduChannel apduChannel) {
|
|
||||||
|
|
||||||
this.apduChannel = apduChannel;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Map<String, String>> run() {
|
|
||||||
String profilesInfo = getProfileInfoListResponse();
|
|
||||||
ProfileInfoListResponse profiles = new ProfileInfoListResponse();
|
|
||||||
List<Map<String, String>> profileList = new ArrayList<>();
|
|
||||||
|
|
||||||
try {
|
|
||||||
decodeProfiles(profilesInfo, profiles);
|
|
||||||
|
|
||||||
for (ProfileInfo info : profiles.getProfileInfoListOk().getProfileInfo()) {
|
|
||||||
Map<String, String> profileMap = new HashMap<>();
|
|
||||||
|
|
||||||
profileMap.put(ProfileKey.STATE.name(), LocalProfileAssistantImpl.DISABLED_STATE.equals(info.getProfileState().toString()) ? "Disabled" : "Enabled");
|
|
||||||
profileMap.put(ProfileKey.ICCID.name(), info.getIccid().toString());
|
|
||||||
profileMap.put(ProfileKey.ICCID_LITTLE.name(), iccidBigToLittle(info.getIccid().toString()));
|
|
||||||
profileMap.put(ProfileKey.NAME.name(), (info.getProfileName()!=null)?info.getProfileName().toString():"");
|
|
||||||
profileMap.put(ProfileKey.NICKNAME.name(), (info.getProfileNickname()!=null)?info.getProfileNickname().toString():"");
|
|
||||||
profileMap.put(ProfileKey.PROVIDER_NAME.name(), (info.getServiceProviderName()!=null)?info.getServiceProviderName().toString():"");
|
|
||||||
profileMap.put(ProfileKey.ISDP_AID.name(), (info.getIsdpAid()!=null)?info.getIsdpAid().toString():"");
|
|
||||||
profileMap.put(ProfileKey.PROFILE_CLASS.name(), (info.getProfileClass()!=null)?info.getProfileClass().toString():"");
|
|
||||||
profileMap.put(ProfileKey.PROFILE_STATE.name(), info.getProfileState().toString());
|
|
||||||
|
|
||||||
profileList.add(profileMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LogStub.getInstance().isDebugEnabled()) {
|
|
||||||
LogStub.getInstance().logDebug (LOG, LogStub.getInstance().getTag() + " - getProfiles - returning: " + profileList.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return profileList;
|
|
||||||
|
|
||||||
} catch (DecoderException e) {
|
|
||||||
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + e.getMessage(), e);
|
|
||||||
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - Unable to retrieve profiles. Exception in Decoder:" + e.getMessage());
|
|
||||||
|
|
||||||
throw new RuntimeException("Unable to retrieve profiles");
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
LOG.log(Level.SEVERE, LogStub.getInstance().getTag() + " - " + ioe.getMessage(), ioe);
|
|
||||||
|
|
||||||
throw new RuntimeException("Unable to retrieve profiles");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void decodeProfiles(String profilesInfo, ProfileInfoListResponse profiles) throws DecoderException, IOException {
|
|
||||||
InputStream is = new ByteArrayInputStream(Hex.decodeHex(profilesInfo.toCharArray()));
|
|
||||||
|
|
||||||
profiles.decode(is);
|
|
||||||
|
|
||||||
if (LogStub.getInstance().isDebugEnabled()) {
|
|
||||||
LogStub.getInstance().logDebug (LOG,"Profile list object: " + profiles.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getProfileInfoListResponse() {
|
|
||||||
|
|
||||||
if (LogStub.getInstance().isDebugEnabled()) {
|
|
||||||
LogStub.getInstance().logDebug (LOG, LogStub.getInstance().getTag() + " - Getting Profiles");
|
|
||||||
}
|
|
||||||
|
|
||||||
String apdu = ApduUtils.getProfilesInfoApdu(null);
|
|
||||||
|
|
||||||
if (LogStub.getInstance().isDebugEnabled()) {
|
|
||||||
LogStub.getInstance().logDebug (LOG,"List profiles APDU: " + apdu);
|
|
||||||
}
|
|
||||||
|
|
||||||
return apduChannel.transmitAPDU(apdu);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String iccidBigToLittle(String iccid) {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
for (int i = 0; i < iccid.length() / 2; i++) {
|
|
||||||
builder.append(iccid.charAt(i * 2 + 1));
|
|
||||||
if (iccid.charAt(i * 2) != 'F')
|
|
||||||
builder.append(iccid.charAt(i * 2));
|
|
||||||
}
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 Peter Cai & Pierre-Hugues Husson
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program.
|
||||||
|
* If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.truphone.lpa.impl
|
||||||
|
|
||||||
|
import com.truphone.lpa.ApduChannel
|
||||||
|
import com.truphone.lpa.LocalProfileInfo
|
||||||
|
import com.truphone.rsp.dto.asn1.rspdefinitions.ProfileInfoListResponse
|
||||||
|
import com.truphone.util.LogStub
|
||||||
|
import org.apache.commons.codec.DecoderException
|
||||||
|
import org.apache.commons.codec.binary.Hex
|
||||||
|
import com.truphone.lpa.apdu.ApduUtils
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.lang.RuntimeException
|
||||||
|
import java.util.logging.Level
|
||||||
|
import java.util.logging.Logger
|
||||||
|
|
||||||
|
internal class ListProfilesWorker(private val apduChannel: ApduChannel) {
|
||||||
|
fun run(): List<LocalProfileInfo> {
|
||||||
|
val profilesInfo = profileInfoListResponse
|
||||||
|
val profiles = ProfileInfoListResponse()
|
||||||
|
val profileList: MutableList<LocalProfileInfo> = mutableListOf()
|
||||||
|
return try {
|
||||||
|
decodeProfiles(profilesInfo, profiles)
|
||||||
|
for (info in profiles.profileInfoListOk.profileInfo) {
|
||||||
|
profileList.add(
|
||||||
|
LocalProfileInfo(
|
||||||
|
iccid = info.iccid.toString(),
|
||||||
|
state = LocalProfileInfo.stateFromString(info.profileState?.toString()),
|
||||||
|
name = info.profileName?.toString() ?: "",
|
||||||
|
nickName = info.profileNickname?.toString() ?: "",
|
||||||
|
providerName = info.serviceProviderName?.toString() ?: "",
|
||||||
|
isdpAID = info.isdpAid?.toString() ?: "",
|
||||||
|
profileClass = LocalProfileInfo.classFromString(info.profileClass?.toString())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (LogStub.getInstance().isDebugEnabled) {
|
||||||
|
LogStub.getInstance().logDebug(
|
||||||
|
LOG,
|
||||||
|
LogStub.getInstance().tag + " - getProfiles - returning: " + profileList.toString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
profileList
|
||||||
|
} catch (e: DecoderException) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().tag + " - " + e.message, e)
|
||||||
|
LOG.log(
|
||||||
|
Level.SEVERE,
|
||||||
|
LogStub.getInstance().tag + " - Unable to retrieve profiles. Exception in Decoder:" + e.message
|
||||||
|
)
|
||||||
|
throw RuntimeException("Unable to retrieve profiles")
|
||||||
|
} catch (ioe: IOException) {
|
||||||
|
LOG.log(Level.SEVERE, LogStub.getInstance().tag + " - " + ioe.message, ioe)
|
||||||
|
throw RuntimeException("Unable to retrieve profiles")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(DecoderException::class, IOException::class)
|
||||||
|
private fun decodeProfiles(profilesInfo: String, profiles: ProfileInfoListResponse) {
|
||||||
|
val `is`: InputStream = ByteArrayInputStream(Hex.decodeHex(profilesInfo.toCharArray()))
|
||||||
|
profiles.decode(`is`)
|
||||||
|
if (LogStub.getInstance().isDebugEnabled) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, "Profile list object: $profiles")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val profileInfoListResponse: String
|
||||||
|
get() {
|
||||||
|
if (LogStub.getInstance().isDebugEnabled) {
|
||||||
|
LogStub.getInstance()
|
||||||
|
.logDebug(LOG, LogStub.getInstance().tag + " - Getting Profiles")
|
||||||
|
}
|
||||||
|
val apdu = ApduUtils.getProfilesInfoApdu(null)
|
||||||
|
if (LogStub.getInstance().isDebugEnabled) {
|
||||||
|
LogStub.getInstance().logDebug(LOG, "List profiles APDU: $apdu")
|
||||||
|
}
|
||||||
|
return apduChannel.transmitAPDU(apdu)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val LOG = Logger.getLogger(
|
||||||
|
ListProfilesWorker::class.java.name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package com.truphone.lpa.impl;
|
||||||
import com.truphone.es9plus.Es9PlusImpl;
|
import com.truphone.es9plus.Es9PlusImpl;
|
||||||
import com.truphone.lpa.ApduChannel;
|
import com.truphone.lpa.ApduChannel;
|
||||||
import com.truphone.lpa.LocalProfileAssistant;
|
import com.truphone.lpa.LocalProfileAssistant;
|
||||||
|
import com.truphone.lpa.LocalProfileInfo;
|
||||||
import com.truphone.lpa.apdu.ApduUtils;
|
import com.truphone.lpa.apdu.ApduUtils;
|
||||||
import com.truphone.lpa.apdu.NotificationType;
|
import com.truphone.lpa.apdu.NotificationType;
|
||||||
import com.truphone.lpa.progress.DownloadProgress;
|
import com.truphone.lpa.progress.DownloadProgress;
|
||||||
|
@ -90,8 +91,7 @@ public class LocalProfileAssistantImpl implements LocalProfileAssistant {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Map<String, String>> getProfiles() {
|
public List<LocalProfileInfo> getProfiles() {
|
||||||
|
|
||||||
return new ListProfilesWorker(apduChannel).run();
|
return new ListProfilesWorker(apduChannel).run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue