Updated on 2026-08-14

This commit is contained in:
Tangem 2018-07-07 00:58:19 +03:00
parent 28f58e8059
commit cb6678380f
10 changed files with 302 additions and 192 deletions

View file

@ -44,7 +44,7 @@ public class VerificationServerProtocol {
http.setRequestMethod("POST"); // PUT is another valid option
http.setDoOutput(true);
String sRequestBody = getGson().toJson(this);
String sRequestBody = getGson().toJson(this.command);
byte[] out = sRequestBody.getBytes(StandardCharsets.UTF_8);
int length = out.length;
@ -107,7 +107,7 @@ public class VerificationServerProtocol {
}
}
static class ResultItem {
public static class ResultItem {
public ResultItem(RequestItem request) {
CID = request.CID;
}
@ -117,15 +117,16 @@ public class VerificationServerProtocol {
public Boolean passed;
}
static class Answer extends CustomAnswer {
public static class Answer extends CustomAnswer {
public ResultItem[] results;
}
public Request prepare(TangemCard card)
public static Request prepare(TangemCard card)
{
Command c=new Command();
c.requests=new RequestItem[1];
c.requests[0].CID= Util.bytesToHex(card.getCID());
c.requests[0]=new RequestItem();
c.requests[0].CID=Util.bytesToHex(card.getCID());
c.requests[0].publicKey=Util.bytesToHex(card.getCardPublicKey());
return new Request(c,Answer.class);

View file

@ -4,10 +4,17 @@ import android.content.Context;
import android.nfc.tech.IsoDep;
import android.util.Log;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.FW;
import com.tangem.domain.cardReader.NfcManager;
import com.tangem.domain.wallet.PINStorage;
import com.tangem.domain.wallet.TangemCard;
import com.tangem.util.Util;
import java.util.Arrays;
/**
* Created by dvol on 04.02.2018.
@ -59,23 +66,26 @@ public class VerifyCardTask extends Thread {
protocol.setPIN(PIN);
protocol.run_Read();
PINStorage.setLastUsedPIN(PIN);
mNotifications.OnReadProgress(protocol, 30);
mNotifications.OnReadProgress(protocol, 20);
if (isCancelled) return;
protocol.run_VerifyCard();
mNotifications.OnReadProgress(protocol, 60);
mNotifications.OnReadProgress(protocol, 50);
Log.i(TAG, "Manufacturer: " + protocol.getCard().getManufacturer().getOfficialName());
if (isCancelled) return;
if (protocol.getCard().getStatus() == TangemCard.Status.Loaded) {
protocol.run_CheckWalletWithSignatureVerify();
mNotifications.OnReadProgress(protocol, 90);
mNotifications.OnReadProgress(protocol, 80);
}
// if (isCancelled) return;
// if (protocol.getCard().getStatus() == TangemCard.Status.Loaded) {
// protocol.run_CheckWithSignatureVerify();
// }
if (isCancelled) return;
FW.VerifyCodeRecord record=FW.selectRandomVerifyCodeBlock(mCard.getFirmwareVersion());
if (isCancelled) return;
if( record!=null ) {
byte[] returnedDigest = protocol.run_VerifyCode(record.hashAlg, record.blockIndex, record.blockCount, record.challenge);
mCard.setCodeConfirmed(Arrays.equals(returnedDigest, record.digest));
}else{
mCard.setCodeConfirmed(null);
}
mNotifications.OnReadProgress(protocol, 90);
} catch (Exception e) {
e.printStackTrace();
protocol.setError(e);

View file

@ -887,7 +887,7 @@ public class CardProtocol {
}
}
private byte[] run_VerifyCode(String hashAlgID, int codePageAddress, int codePageCount, byte[] challenge) throws Exception {
public byte[] run_VerifyCode(String hashAlgID, int codePageAddress, int codePageCount, byte[] challenge) throws Exception {
if (readResult == null) run_Read();
CommandApdu rqApdu = StartPrepareCommand(INS.VerifyCode);
rqApdu.addTLV(TLV.Tag.TAG_HashAlgID, hashAlgID.getBytes("US-ASCII"));

View file

@ -0,0 +1,62 @@
package com.tangem.domain.cardReader;
import android.content.Context;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.tangem.util.Util;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
public class FW {
private static JsonArray jaFirmwares=null;
public static boolean needInit() {
return jaFirmwares == null;
}
public static void Init(Context context) {
try(InputStream is=context.getAssets().open("fw_hashes.json")) {
try (InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
JsonParser parser = new JsonParser();
jaFirmwares = parser.parse(reader).getAsJsonArray();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static class VerifyCodeRecord
{
public String hashAlg;
public int blockIndex;
public int blockCount;
public byte[] challenge;
public byte[] digest;
}
public static VerifyCodeRecord selectRandomVerifyCodeBlock(String firmwareVersion) throws IOException {
for(int i=0; i<jaFirmwares.size(); i++) {
JsonObject jsVersion = jaFirmwares.get(i).getAsJsonObject();
if( jsVersion.get("fw").getAsString().equals(firmwareVersion) )
{
VerifyCodeRecord result=new VerifyCodeRecord();
result.hashAlg = "sha-256";
JsonArray jsHashes = jsVersion.get(result.hashAlg).getAsJsonArray();
result.challenge = Util.hexToBytes(jsVersion.get("challenge").getAsString());
int caseIndex= Util.byteArrayToInt(Util.generateRandomBytes(4))%jsHashes.size();
JsonObject jsRecord = jsHashes.get(caseIndex).getAsJsonObject();
result.blockIndex = jsRecord.get("block").getAsInt();
result.blockCount = jsRecord.get("count").getAsInt();
result.digest = Util.hexToBytes(jsRecord.get("digest").getAsString());
return result;
}
}
return null;
}
}

View file

@ -1,24 +1,19 @@
package com.tangem.domain.wallet;
import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
import com.google.common.io.Files;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import com.tangem.domain.cardReader.CardCrypto;
import com.tangem.util.Util;
import com.tangem.wallet.R;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -27,121 +22,9 @@ import java.util.List;
* Created by dvol on 14.11.2017.
*/
//public enum Issuer {
// Unknown("Unknown", "Unknown", null, null, null, null),
// SMART_CASH_AG("SMART CASH AG", "SMART CASH AG",
// IssuerKeyStorage.sdkPrivateDataKey, IssuerKeyStorage.GeneratePublicKey(IssuerKeyStorage.sdkPrivateDataKey),
// IssuerKeyStorage.sdkPrivateTransactionKey, IssuerKeyStorage.GeneratePublicKey(IssuerKeyStorage.sdkPrivateTransactionKey)),
// TANGEM_SDK("TANGEM SDK", "TANGEM SDK",
// IssuerKeyStorage.sdkPrivateDataKey, IssuerKeyStorage.GeneratePublicKey(IssuerKeyStorage.sdkPrivateDataKey),
// IssuerKeyStorage.sdkPrivateTransactionKey, IssuerKeyStorage.GeneratePublicKey(IssuerKeyStorage.sdkPrivateTransactionKey)),
// TANGEM("TANGEM", "TANGEM", null, IssuerKeyStorage.tangemPublicDataKey, null, IssuerKeyStorage.tangemPublicTransactionKey)
// ;
//
//
// static class IssuerKeyStorage {
// private static final byte[] sdkPrivateDataKey = new byte[]{
// (byte) 0x11, (byte) 0x12, (byte) 0x13, (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17, (byte) 0x18,
// (byte) 0x47, (byte) 0x71, (byte) 0xED, (byte) 0x81, (byte) 0xF2, (byte) 0xBA, (byte) 0xCF, (byte) 0x57,
// (byte) 0x47, (byte) 0x9E, (byte) 0x47, (byte) 0x35, (byte) 0xEB, (byte) 0x14, (byte) 0x05, (byte) 0x08,
// (byte) 0x39, (byte) 0x27, (byte) 0x37, (byte) 0x2D, (byte) 0x40, (byte) 0xDA, (byte) 0x9E, (byte) 0x92};
//
// private static final byte[] sdkPrivateTransactionKey = new byte[]{
// (byte) 0x11, (byte) 0x12, (byte) 0x13, (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17, (byte) 0x18,
// (byte) 0x47, (byte) 0x71, (byte) 0xED, (byte) 0x81, (byte) 0xF2, (byte) 0xBA, (byte) 0xCF, (byte) 0x57,
// (byte) 0x47, (byte) 0x9E, (byte) 0x47, (byte) 0x35, (byte) 0xEB, (byte) 0x14, (byte) 0x05, (byte) 0x08,
// (byte) 0x19, (byte) 0x18, (byte) 0x17, (byte) 0x16, (byte) 0x15, (byte) 0x14, (byte) 0x13, (byte) 0x12};
//
// private static byte[] tangemPublicDataKey = {
// (byte) 0x04 ,
// (byte) 0x81 ,(byte) 0x96 ,(byte) 0xAA ,(byte) 0x4B ,(byte) 0x41 ,(byte) 0x0A ,(byte) 0xC4 ,(byte) 0x4A,
// (byte) 0x3B ,(byte) 0x9C ,(byte) 0xCE ,(byte) 0x18 ,(byte) 0xE7 ,(byte) 0xBE ,(byte) 0x22 ,(byte) 0x6A,
// (byte) 0xEA ,(byte) 0x07 ,(byte) 0x0A ,(byte) 0xCC ,(byte) 0x83 ,(byte) 0xA9 ,(byte) 0xCF ,(byte) 0x67,
// (byte) 0x54 ,(byte) 0x0F ,(byte) 0xAC ,(byte) 0x49 ,(byte) 0xAF ,(byte) 0x25 ,(byte) 0x12 ,(byte) 0x9F,
// (byte) 0x6A ,(byte) 0x53 ,(byte) 0x8A ,(byte) 0x28 ,(byte) 0xAD ,(byte) 0x63 ,(byte) 0x41 ,(byte) 0x35,
// (byte) 0x8E ,(byte) 0x3C ,(byte) 0x4F ,(byte) 0x99 ,(byte) 0x63 ,(byte) 0x06 ,(byte) 0x4F ,(byte) 0x7E,
// (byte) 0x36 ,(byte) 0x53 ,(byte) 0x72 ,(byte) 0xA6 ,(byte) 0x51 ,(byte) 0xD3 ,(byte) 0x74 ,(byte) 0xE5,
// (byte) 0xC2 ,(byte) 0x3C ,(byte) 0xDD ,(byte) 0x37 ,(byte) 0xFD ,(byte) 0x09 ,(byte) 0x9B ,(byte) 0xF2};
//
// private static byte[] tangemPublicTransactionKey = {
// (byte) 0x04 ,
// (byte) 0x34 ,(byte) 0x3D ,(byte) 0x40 ,(byte) 0x49 ,(byte) 0x6C ,(byte) 0xBE ,(byte) 0x1F ,(byte) 0xE8,
// (byte) 0xA8 ,(byte) 0xC0 ,(byte) 0x26 ,(byte) 0x57 ,(byte) 0x5C ,(byte) 0x43 ,(byte) 0x5A ,(byte) 0x29,
// (byte) 0x14 ,(byte) 0x1E ,(byte) 0xA3 ,(byte) 0xBC ,(byte) 0x33 ,(byte) 0x5D ,(byte) 0xA5 ,(byte) 0x54,
// (byte) 0x9A ,(byte) 0xB6 ,(byte) 0xC6 ,(byte) 0x46 ,(byte) 0x85 ,(byte) 0xA6 ,(byte) 0x46 ,(byte) 0x84,
// (byte) 0x80 ,(byte) 0x36 ,(byte) 0xD4 ,(byte) 0x81 ,(byte) 0xCF ,(byte) 0x9A ,(byte) 0x98 ,(byte) 0x93,
// (byte) 0x90 ,(byte) 0xA8 ,(byte) 0xB0 ,(byte) 0x34 ,(byte) 0xB2 ,(byte) 0x29 ,(byte) 0xD9 ,(byte) 0x9B,
// (byte) 0xD4 ,(byte) 0x9E ,(byte) 0x6F ,(byte) 0x07 ,(byte) 0xD2 ,(byte) 0xFF ,(byte) 0x02 ,(byte) 0x74,
// (byte) 0x6E ,(byte) 0xA2 ,(byte) 0x65 ,(byte) 0xEF ,(byte) 0x99 ,(byte) 0x38 ,(byte) 0x0A ,(byte) 0x80};
//
// public static byte[] GeneratePublicKey(byte[] privateKey) {
// try {
// return CardCrypto.GeneratePublicKey(privateKey);
// }
// catch (Exception e)
// {
// e.printStackTrace();
// return null;
// }
// }
// }
//
// private String ID;
// private String officialName;
// private byte[] privateDataKeyArray;
// private byte[] publicDataKeyArray;
// private byte[] privateTransactionKeyArray;
// private byte[] publicTransactionKeyArray;
//
// Issuer(String id, String officialName, byte[] privateDataKey, byte[] publicDataKey, byte[] privateTransactionKey, byte[] publicTransactionKey) {
// this.ID = id;
// this.officialName = officialName;
// this.privateDataKeyArray = privateDataKey;
// this.privateTransactionKeyArray = privateTransactionKey;
// this.publicDataKeyArray = publicDataKey;
// this.publicTransactionKeyArray = publicTransactionKey;
// }
//
// public byte[] getPublicDataKey() {
// return publicDataKeyArray;
// }
//
// public byte[] getPublicTransactionKey() {
// return publicTransactionKeyArray;
// }
//
// public byte[] getPrivateDataKey() {
// return privateDataKeyArray;
// }
//
// public byte[] getPrivateTransactionKey() {
// return privateTransactionKeyArray;
// }
//
// public byte[] getID() {
// return ID.getBytes();
// }
//
// public String getOfficialName() {
// return officialName;
// }
//
// public static Issuer FindIssuer(String ID, byte[] publicDataKey) {
// Issuer[] issuers = Issuer.values();
// for (int i = 1; i < issuers.length; i++) {
// if (issuers[i].ID.equals(ID) && Arrays.equals(issuers[i].getPublicDataKey(), publicDataKey)) {
// return issuers[i];
// }
// }
// return Issuer.Unknown;
// }
//
//}
public class Issuer {
static class KeyPair
{
static class KeyPair {
String privateKey;
String publicKey;
@ -166,10 +49,11 @@ public class Issuer {
}
}
String id;
String officialName;
KeyPair dataKey;
KeyPair transactionKey;
private String id;
private String officialName;
private KeyPair dataKey;
private KeyPair transactionKey;
public String getID() {
return id;
@ -178,83 +62,102 @@ public class Issuer {
private static List<Issuer> instances=new ArrayList<>();
public static boolean needInit() {
return instances.size()==0;
return instances.size() == 0;
}
public static void Init(Context mContext){
public static void Init(Context context) {
try {
JsonArray jaIssuers;
JsonParser jsonParser=new JsonParser();
jaIssuers=jsonParser.parse(ReadJSONResource(mContext, R.raw.issuers)).getAsJsonArray();
instances.clear();
Issuer unknown=new Issuer();
unknown.id="UNKNOWN";
unknown.officialName="UNKNOWN";
instances.add(unknown);
// JsonArray jaIssuers=loadIssuersFile();
//
Issuer unknown = new Issuer();
unknown.id = "UNKNOWN";
unknown.officialName = "UNKNOWN";
for(JsonElement jeIssuer: jaIssuers)
{
Issuer instance=new Gson().fromJson(jeIssuer,Issuer.class);
instances.add(instance);
try(InputStream is=context.getAssets().open("issuers.json")) {
try ( InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
Type listType = new TypeToken<List<Issuer>>() {
}.getType();
instances = new Gson().fromJson(reader, listType);
}
}
instances.add(0, unknown);
// for (JsonElement jeIssuer : jaIssuers) {
// Issuer instance = new Gson().fromJson(jeIssuer, Issuer.class);
// instances.add(instance);
// }
} catch (Exception e) {
e.printStackTrace();
}
}
static String ReadJSONResource(Context mContext, int id) {
Resources resources = mContext.getResources();
InputStream resourceReader = resources.openRawResource(id);
Writer writer = new StringWriter();
try {
try(BufferedReader reader = new BufferedReader(new InputStreamReader(resourceReader, "UTF-8"))) {
String line = reader.readLine();
while (line != null) {
writer.write(line);
line = reader.readLine();
}
}
} catch (Exception e) {
Log.e("ReadJSONResource", "Unhandled exception while using JSONResourceReader", e);
} finally {
try {
resourceReader.close();
} catch (Exception e) {
Log.e("ReadJSONResource", "Unhandled exception while using JSONResourceReader", e);
}
}
return writer.toString();
}
// private static JsonArray loadIssuersFile() throws IOException {
// String result;
// JsonParser jsonParser = new JsonParser();
// try (BufferedReader reader = Files.newReader(new File("Issuers.json"), StandardCharsets.UTF_8)) {
// String str;
// StringBuilder buf = new StringBuilder();
// while ((str = reader.readLine()) != null) {
// buf.append(str);
// buf.append("\n");
// }
// result = buf.toString();
// }
// return jsonParser.parse(result).getAsJsonArray();
// }
//
// static String ReadJSONResource(Context mContext, int id) {
// Resources resources = mContext.getResources();
// InputStream resourceReader = resources.openRawResource(id);
// Writer writer = new StringWriter();
// try {
// try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceReader, "UTF-8"))) {
// String line = reader.readLine();
// while (line != null) {
// writer.write(line);
// line = reader.readLine();
// }
// }
// } catch (Exception e) {
// Log.e("ReadJSONResource", "Unhandled exception while using JSONResourceReader", e);
// } finally {
// try {
// resourceReader.close();
// } catch (Exception e) {
// Log.e("ReadJSONResource", "Unhandled exception while using JSONResourceReader", e);
// }
// }
//
// return writer.toString();
// }
public byte[] getPublicDataKey() throws Exception {
if( dataKey==null )
if (dataKey == null)
throw new Exception("Data key not specified!");
return dataKey.getPublicKey();
}
public byte[] getPublicTransactionKey() throws Exception {
if( dataKey==null )
if (dataKey == null)
throw new Exception("Transaction key not specified!");
return transactionKey.getPublicKey();
}
public byte[] getPrivateDataKey() throws Exception {
if( dataKey==null )
if (dataKey == null)
throw new Exception("Data key not specified!");
return dataKey.getPrivateKey();
}
public byte[] getPrivateTransactionKey() throws Exception {
if( transactionKey==null )
if (transactionKey == null)
throw new Exception("Transaction key not specified!");
return transactionKey.getPrivateKey();
}
public String getOfficialName() {
return officialName!=null?officialName:id;
return officialName != null ? officialName : id;
}
public static Issuer FindIssuer(String ID) {

View file

@ -269,6 +269,33 @@ public class TangemCard {
}
}
private Boolean codeConfirmed;
public void setCodeConfirmed(Boolean codeConfirmed) {
this.codeConfirmed = codeConfirmed;
}
public Boolean isCodeConfirmed() {
return codeConfirmed;
}
private Boolean onlineVerified;
public void setOnlineVerified(Boolean verified) {
this.onlineVerified = verified;
}
public Boolean isOnlineVerified() {
return onlineVerified;
}
private Boolean onlineValidated;
public void setOnlineValidated(Boolean validated) {
this.onlineValidated = validated;
}
public Boolean isOnlineValidated() {
return onlineValidated;
}
public int getRemainingSignatures() {
return remainingSignatures;
}
@ -1254,6 +1281,19 @@ public class TangemCard {
B.putFloat("rate", rate);
B.putFloat("rateAlter", rateAlter);
B.putString("confirmTx", GetConfirmTXCount().toString(16));
if( codeConfirmed!=null )
B.putBoolean("codeConfirmed", codeConfirmed);
if( codeConfirmed!=null )
B.putBoolean("codeConfirmed", codeConfirmed);
if( onlineVerified!=null )
B.putBoolean("onlineVerified", onlineVerified);
if( onlineValidated!=null )
B.putBoolean("onlineValidated", onlineValidated);
}
public void LoadFromBundle(Bundle B) {
@ -1363,6 +1403,15 @@ public class TangemCard {
rateAlter = B.getFloat("rateAlter");
if (B.containsKey("confirmTx"))
countConfirmTX = new BigInteger(B.getString("confirmTx"), 16);
if( B.containsKey("codeConfirmed") )
codeConfirmed=B.getBoolean("codeConfirmed");
if( B.containsKey("onlineVerified") )
onlineVerified=B.getBoolean("onlineVerified");
if( B.containsKey("onlineValidated") )
onlineValidated=B.getBoolean("onlineValidated");
}
public int getCardImageResource() {

View file

@ -3,6 +3,7 @@ package com.tangem.presentation.activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.AssetManager;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
@ -23,6 +24,7 @@ import android.widget.TextView;
import com.scottyab.rootbeer.RootBeer;
import com.skyfishjy.library.RippleBackground;
import com.tangem.domain.cardReader.FW;
import com.tangem.domain.wallet.DeviceNFCAntennaLocation;
import com.tangem.domain.wallet.Issuer;
import com.tangem.domain.wallet.LastSignStorage;
@ -217,10 +219,8 @@ public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuI
if (LastSignStorage.needInit()) {
LastSignStorage.Init(context);
}
if(Issuer.needInit())
{
Issuer.Init(context);
}
if( Issuer.needInit() ) Issuer.Init(context);
if( FW.needInit() ) FW.Init(context);
}
public void showCleanButton() {

View file

@ -35,9 +35,11 @@ import com.google.zxing.WriterException;
import com.tangem.data.network.request.ElectrumRequest;
import com.tangem.data.network.request.ExchangeRequest;
import com.tangem.data.network.request.InfuraRequest;
import com.tangem.data.network.request.VerificationServerProtocol;
import com.tangem.data.network.task.ElectrumTask;
import com.tangem.data.network.task.ExchangeTask;
import com.tangem.data.network.task.InfuraTask;
import com.tangem.data.network.task.VerificationServerTask;
import com.tangem.data.nfc.VerifyCardTask;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.NfcManager;
@ -113,7 +115,8 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre
private ImageView ivPIN2orSecurityDelay;
private ImageView ivDeveloperVersion;
private SwipeRefreshLayout mSwipeRefreshLayout;
private List<UpdateWalletInfoTask> updateTasks = new ArrayList<>();
private List<AsyncTask> updateTasks = new ArrayList<>();
OnlineVerifyTask onlineVerifyTask;
private NfcManager mNfcManager;
private boolean lastReadSuccess = true;
private VerifyCardTask verifyCardTask = null;
@ -561,6 +564,42 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre
}
}
private class OnlineVerifyTask extends VerificationServerTask {
@Override
protected void onCancelled() {
super.onCancelled();
updateTasks.remove(this);
onlineVerifyTask=null;
if (updateTasks.size() == 0) mSwipeRefreshLayout.setRefreshing(false);
}
@Override
protected void onPostExecute(List<VerificationServerProtocol.Request> requests) {
super.onPostExecute(requests);
Log.i("OnlineVerifyTask", "onPostExecute[" + String.valueOf(updateTasks.size()) + "]");
updateTasks.remove(this);
onlineVerifyTask=null;
for (VerificationServerProtocol.Request request : requests) {
if (request.error == null) {
VerificationServerProtocol.Verify.Answer answer = (VerificationServerProtocol.Verify.Answer) request.answer;
if (answer.error == null) {
mCard.setOnlineVerified(answer.results[0].passed);
} else {
mCard.setOnlineVerified(null);
errorOnUpdate(request.error);
}
} else {
mCard.setOnlineVerified(null);
errorOnUpdate(request.error);
}
}
if (updateTasks.size() == 0) mSwipeRefreshLayout.setRefreshing(false);
}
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -639,6 +678,12 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre
mSwipeRefreshLayout.postDelayed(this::onRefresh, 1000);
}
if ( (mCard.isOnlineVerified()==null || !mCard.isOnlineVerified()) && onlineVerifyTask ==null) {
onlineVerifyTask = new OnlineVerifyTask();
updateTasks.add(onlineVerifyTask);
onlineVerifyTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, VerificationServerProtocol.Verify.prepare(mCard));
}
imgLookup.setOnClickListener(v15 -> {
if (!mCard.hasBalanceInfo()) return;
CoinEngine engineClick = CoinEngineFactory.Create(mCard.getBlockchain());
@ -734,7 +779,7 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre
@Override
public void onStop() {
super.onStop();
for (UpdateWalletInfoTask ut : updateTasks) {
for (AsyncTask ut : updateTasks) {
ut.cancel(true);
}
mNfcManager.onStop();
@ -926,6 +971,12 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre
updateViews();
if ( (mCard.isOnlineVerified()==null || !mCard.isOnlineVerified()) && onlineVerifyTask ==null) {
onlineVerifyTask = new OnlineVerifyTask();
updateTasks.add(onlineVerifyTask);
onlineVerifyTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, VerificationServerProtocol.Verify.prepare(mCard));
}
CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
if (mCard.getBlockchain() == Blockchain.Bitcoin || mCard.getBlockchain() == Blockchain.BitcoinTestNet) {