From b5c0595723500b2e06700245e32591b4db09a539 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 26 Jun 2018 21:32:46 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/data/task/ReadCardInfoTask.java | 167 ++++++++++++++++ .../{network => }/task/VerifyCardTask.java | 19 +- .../activity/EmptyWalletActivity.java | 2 +- .../activity/LoadedWalletActivity.java | 4 + .../presentation/activity/MainActivity.java | 7 +- .../presentation/fragment/LoadedWallet.java | 2 +- .../tangem/presentation/fragment/Main.java | 182 ++---------------- app/src/main/res/layout/fr_verify_card.xml | 42 ++-- 8 files changed, 225 insertions(+), 200 deletions(-) create mode 100644 app/src/main/java/com/tangem/data/task/ReadCardInfoTask.java rename app/src/main/java/com/tangem/data/{network => }/task/VerifyCardTask.java (87%) diff --git a/app/src/main/java/com/tangem/data/task/ReadCardInfoTask.java b/app/src/main/java/com/tangem/data/task/ReadCardInfoTask.java new file mode 100644 index 0000000000..0e3c070512 --- /dev/null +++ b/app/src/main/java/com/tangem/data/task/ReadCardInfoTask.java @@ -0,0 +1,167 @@ +package com.tangem.data.task; + +import android.content.Context; +import android.nfc.tech.IsoDep; +import android.util.Log; + +import com.tangem.domain.cardReader.CardProtocol; +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.ArrayList; + +public class ReadCardInfoTask extends Thread { + public static final String TAG = ReadCardInfoTask.class.getSimpleName(); + + private IsoDep mIsoDep; + private CardProtocol.Notifications mNotifications; + private boolean isCancelled = false; + private Context mContext; + private NfcManager mNfcManager; + + private ArrayList lastRead_UnsuccessfullPINs = new ArrayList<>(); + private TangemCard.EncryptionMode lastRead_Encryption = null; + private String lastRead_UID; + + public ReadCardInfoTask(Context context, NfcManager nfcManager, String lastRead_UID, IsoDep isoDep, CardProtocol.Notifications notifications) { + mContext = context; + mIsoDep = isoDep; + mNotifications = notifications; + mNfcManager = nfcManager; + this.lastRead_UID = lastRead_UID; + } + + @Override + public void run() { + if (mIsoDep == null) { + return; + } + try { + // for Samsung's bugs - + // Workaround for the Samsung Galaxy S5 (since the + // first connection always hangs on transceive). + int timeout = mIsoDep.getTimeout(); + mIsoDep.connect(); + mIsoDep.close(); + mIsoDep.connect(); + mIsoDep.setTimeout(timeout); + try { + CardProtocol protocol = new CardProtocol(mContext, mIsoDep, mNotifications); + mNotifications.OnReadStart(protocol); + try { + mNotifications.OnReadProgress(protocol, 5); + + byte[] UID = mIsoDep.getTag().getId(); + String sUID = Util.byteArrayToHexString(UID); + if (!lastRead_UID.equals(sUID)) { + lastRead_UID = sUID; + lastRead_UnsuccessfullPINs.clear(); + lastRead_Encryption = null; + } + + Log.i(TAG, "[-- Start read card info --]"); + + if (isCancelled) return; + + protocol.setPIN(PINStorage.getDefaultPIN()); + protocol.clearReadResult(); + + if (lastRead_Encryption == null) { + Log.i(TAG, "Try get supported encryption mode"); + protocol.run_GetSupportedEncryption(); + } else { + Log.i(TAG, "Use already defined encryption mode: " + lastRead_Encryption.name()); + protocol.getCard().encryptionMode = lastRead_Encryption; + } + + if (protocol.haveReadResult()) { + //already have read result (obtained while get supported encryption), only read issuer data and define offline balance + protocol.parseReadResult(); + protocol.run_ReadOrWriteIssuerDataAndDefineOfflineBalance(); + mNotifications.OnReadProgress(protocol, 60); + PINStorage.setLastUsedPIN(protocol.getCard().getPIN()); + } else { + //don't have read result - may be don't get supported encryption on this try, need encryption or need another PIN + if (lastRead_Encryption == null) { + // we try get supported encryption on this time + lastRead_Encryption = protocol.getCard().encryptionMode; + if (protocol.getCard().encryptionMode == TangemCard.EncryptionMode.None) { + // default pin not accepted + lastRead_UnsuccessfullPINs.add(PINStorage.getDefaultPIN()); + } + } + + boolean pinFound = false; + for (String PIN : PINStorage.getPINs()) { + Log.e(TAG, "PIN: " + PIN); + + boolean skipPin = false; + for (int i = 0; i < lastRead_UnsuccessfullPINs.size(); i++) { + if (lastRead_UnsuccessfullPINs.get(i).equals(PIN)) { + skipPin = true; + break; + } + } + + if (skipPin) { + Log.e(TAG, "Skip PIN - already checked before"); + continue; + } + + try { + protocol.setPIN(PIN); + if (protocol.getCard().encryptionMode != TangemCard.EncryptionMode.None) { + protocol.CreateProtocolKey(); + } + protocol.run_Read(); + mNotifications.OnReadProgress(protocol, 60); + PINStorage.setLastUsedPIN(PIN); + pinFound = true; + protocol.getCard().setPIN(PIN); + break; + } catch (CardProtocol.TangemException_InvalidPIN e) { + Log.e(TAG, e.getMessage()); + lastRead_UnsuccessfullPINs.add(PIN); + } + } + if (!pinFound) { + throw new CardProtocol.TangemException_InvalidPIN("No valid PIN found!"); + } + } + + protocol.run_CheckPIN2isDefault(); + + } catch (Exception e) { + e.printStackTrace(); + protocol.setError(e); + + } finally { + Log.i(TAG, "[-- Finish read card info --]"); + mNotifications.OnReadFinish(protocol); + } + } finally { + mNfcManager.ignoreTag(mIsoDep.getTag()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void cancel(Boolean AllowInterrupt) { + try { + if (this.isAlive()) { + isCancelled = true; + join(500); + } + if (this.isAlive() && AllowInterrupt) { + interrupt(); + mNotifications.OnReadCancel(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/data/network/task/VerifyCardTask.java b/app/src/main/java/com/tangem/data/task/VerifyCardTask.java similarity index 87% rename from app/src/main/java/com/tangem/data/network/task/VerifyCardTask.java rename to app/src/main/java/com/tangem/data/task/VerifyCardTask.java index 3c2658b340..966f410e5d 100644 --- a/app/src/main/java/com/tangem/data/network/task/VerifyCardTask.java +++ b/app/src/main/java/com/tangem/data/task/VerifyCardTask.java @@ -1,4 +1,4 @@ -package com.tangem.data.network.task; +package com.tangem.data.task; import android.content.Context; import android.nfc.tech.IsoDep; @@ -14,10 +14,10 @@ import com.tangem.domain.wallet.TangemCard; */ public class VerifyCardTask extends Thread { + public static final String TAG = VerifyCardTask.class.getSimpleName(); - IsoDep mIsoDep; - CardProtocol.Notifications mNotifications; - private final String logTag = "VerifyCardTask"; + private IsoDep mIsoDep; + private CardProtocol.Notifications mNotifications; private boolean isCancelled = false; private Context mContext; private TangemCard mCard; @@ -51,7 +51,7 @@ public class VerifyCardTask extends Thread { try { mNotifications.OnReadProgress(protocol, 5); - Log.i("VerifyCardTask", "[-- Start verify card --]"); + Log.i(TAG, "[-- Start verify card --]"); if (isCancelled) return; @@ -63,7 +63,7 @@ public class VerifyCardTask extends Thread { if (isCancelled) return; protocol.run_VerifyCard(); mNotifications.OnReadProgress(protocol, 60); - Log.i("VerifyCardTask", "Manufacturer: " + protocol.getCard().getManufacturer().getOfficialName()); + Log.i(TAG, "Manufacturer: " + protocol.getCard().getManufacturer().getOfficialName()); if (isCancelled) return; if (protocol.getCard().getStatus() == TangemCard.Status.Loaded) { protocol.run_CheckWalletWithSignatureVerify(); @@ -71,7 +71,6 @@ public class VerifyCardTask extends Thread { } - // if (isCancelled) return; // if (protocol.getCard().getStatus() == TangemCard.Status.Loaded) { // protocol.run_CheckWithSignatureVerify(); @@ -82,7 +81,7 @@ public class VerifyCardTask extends Thread { protocol.setError(e); } finally { - Log.i("VerifyCardTask", "[-- Finish verify card --]"); + Log.i(TAG, "[-- Finish verify card --]"); mNotifications.OnReadFinish(protocol); } } finally { @@ -93,7 +92,7 @@ public class VerifyCardTask extends Thread { } } - void cancel(Boolean AllowInterrupt) { + public void cancel(Boolean AllowInterrupt) { try { if (this.isAlive()) { isCancelled = true; @@ -108,4 +107,4 @@ public class VerifyCardTask extends Thread { } } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/presentation/activity/EmptyWalletActivity.java b/app/src/main/java/com/tangem/presentation/activity/EmptyWalletActivity.java index 89b61592fe..cd797910dc 100644 --- a/app/src/main/java/com/tangem/presentation/activity/EmptyWalletActivity.java +++ b/app/src/main/java/com/tangem/presentation/activity/EmptyWalletActivity.java @@ -23,7 +23,7 @@ import com.tangem.domain.wallet.TangemCard; import com.tangem.util.Util; import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog; import com.tangem.wallet.R; -import com.tangem.data.network.task.VerifyCardTask; +import com.tangem.data.task.VerifyCardTask; import com.tangem.presentation.dialog.WaitSecurityDelayDialog; public class EmptyWalletActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback, CardProtocol.Notifications { diff --git a/app/src/main/java/com/tangem/presentation/activity/LoadedWalletActivity.java b/app/src/main/java/com/tangem/presentation/activity/LoadedWalletActivity.java index 3707d354b8..c2a7d21012 100644 --- a/app/src/main/java/com/tangem/presentation/activity/LoadedWalletActivity.java +++ b/app/src/main/java/com/tangem/presentation/activity/LoadedWalletActivity.java @@ -6,8 +6,10 @@ import android.nfc.NfcAdapter; import android.nfc.Tag; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; +import android.widget.Toast; import com.tangem.presentation.fragment.LoadedWallet; +import com.tangem.wallet.BuildConfig; import com.tangem.wallet.R; import java.util.Objects; @@ -25,6 +27,8 @@ public class LoadedWalletActivity extends AppCompatActivity { if (tag != null) { LoadedWallet fragment = (LoadedWallet) (getSupportFragmentManager().findFragmentById(R.id.loaded_wallet_fragment)); fragment.onTagDiscovered(tag); + if (BuildConfig.DEBUG) + Toast.makeText(this, "onNFCReaderCallback 4", Toast.LENGTH_SHORT).show(); } } } diff --git a/app/src/main/java/com/tangem/presentation/activity/MainActivity.java b/app/src/main/java/com/tangem/presentation/activity/MainActivity.java index c46686bcb4..530ca746ca 100644 --- a/app/src/main/java/com/tangem/presentation/activity/MainActivity.java +++ b/app/src/main/java/com/tangem/presentation/activity/MainActivity.java @@ -20,6 +20,7 @@ import android.view.animation.Transformation; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; +import android.widget.Toast; import com.scottyab.rootbeer.RootBeer; import com.skyfishjy.library.RippleBackground; @@ -65,6 +66,8 @@ public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuI Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); if (tag != null && onNFCReaderCallback != null) { onNFCReaderCallback.onTagDiscovered(tag); + if (BuildConfig.DEBUG) + Toast.makeText(this, "onNFCReaderCallback 1", Toast.LENGTH_SHORT).show(); } } } @@ -130,6 +133,8 @@ public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuI Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); if (tag != null && onNFCReaderCallback != null) { onNFCReaderCallback.onTagDiscovered(tag); + if (BuildConfig.DEBUG) + Toast.makeText(this, "onNFCReaderCallback 2", Toast.LENGTH_SHORT).show(); } } @@ -197,7 +202,7 @@ public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuI return true; case R.id.cleanCards: - if (onCardsClean != null) onCardsClean.doClean(); + onCardsClean.doClean(); hideCleanButton(); return true; diff --git a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.java b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.java index 77e73e67d2..073d8241ba 100644 --- a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.java +++ b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.java @@ -44,7 +44,7 @@ import com.tangem.data.network.request.InfuraRequest; 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.VerifyCardTask; +import com.tangem.data.task.VerifyCardTask; import com.tangem.domain.cardReader.CardProtocol; import com.tangem.domain.cardReader.NfcManager; import com.tangem.domain.wallet.BitcoinException; diff --git a/app/src/main/java/com/tangem/presentation/fragment/Main.java b/app/src/main/java/com/tangem/presentation/fragment/Main.java index 658db1cd55..21256089a9 100644 --- a/app/src/main/java/com/tangem/presentation/fragment/Main.java +++ b/app/src/main/java/com/tangem/presentation/fragment/Main.java @@ -30,12 +30,12 @@ import com.tangem.data.network.request.InfuraRequest; 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.task.ReadCardInfoTask; import com.tangem.domain.cardReader.CardProtocol; import com.tangem.domain.cardReader.NfcManager; import com.tangem.domain.wallet.Blockchain; import com.tangem.domain.wallet.CoinEngine; import com.tangem.domain.wallet.CoinEngineFactory; -import com.tangem.domain.wallet.PINStorage; import com.tangem.domain.wallet.SharedData; import com.tangem.domain.wallet.TangemCard; import com.tangem.presentation.activity.EmptyWalletActivity; @@ -46,6 +46,7 @@ import com.tangem.presentation.adapter.CardListAdapter; import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog; import com.tangem.presentation.dialog.WaitSecurityDelayDialog; import com.tangem.util.Util; +import com.tangem.wallet.BuildConfig; import com.tangem.wallet.R; import org.json.JSONArray; @@ -67,6 +68,7 @@ public class Main extends Fragment implements NfcAdapter.ReaderCallback, CardLis private static final int REQUEST_CODE_SHOW_CARD_ACTIVITY = 1; private static final int REQUEST_CODE_ENTER_PIN_ACTIVITY = 2; private static final int REQUEST_CODE_REQUEST_CAMERA_PERMISSIONS = 3; + private NfcManager mNfcManager; private ArrayList slCardUIDs = new ArrayList<>(); private ProgressBar progressBar; @@ -76,155 +78,7 @@ public class Main extends Fragment implements NfcAdapter.ReaderCallback, CardLis private int unsuccessReadCount = 0; private Tag lastTag = null; - - - private static String lastRead_UID = ""; - private static ArrayList lastRead_UnsuccessfullPINs = new ArrayList<>(); - private static TangemCard.EncryptionMode lastRead_Encryption = null; - - private class ReadCardInfoTask extends Thread { - - IsoDep mIsoDep; - CardProtocol.Notifications mNotifications; - private boolean isCancelled = false; - - ReadCardInfoTask(IsoDep isoDep, CardProtocol.Notifications notifications) { - mIsoDep = isoDep; - mNotifications = notifications; - } - - @Override - public void run() { - if (mIsoDep == null) { - return; - } - try { - // for Samsung's bugs - - // Workaround for the Samsung Galaxy S5 (since the - // first connection always hangs on transceive). - int timeout = mIsoDep.getTimeout(); - mIsoDep.connect(); - mIsoDep.close(); - mIsoDep.connect(); - mIsoDep.setTimeout(timeout); - try { - CardProtocol protocol = new CardProtocol(getContext(), mIsoDep, mNotifications); - mNotifications.OnReadStart(protocol); - try { - mNotifications.OnReadProgress(protocol, 5); - - byte[] UID = mIsoDep.getTag().getId(); - String sUID = Util.byteArrayToHexString(UID); - if (!lastRead_UID.equals(sUID)) { - lastRead_UID = sUID; - lastRead_UnsuccessfullPINs.clear(); - lastRead_Encryption = null; - } - - Log.i("ReadCardInfoTask", "[-- Start read card info --]"); - - if (isCancelled) return; - - protocol.setPIN(PINStorage.getDefaultPIN()); - protocol.clearReadResult(); - - if (lastRead_Encryption == null) { - Log.i("ReadCardInfoTask", "Try get supported encryption mode"); - protocol.run_GetSupportedEncryption(); - } else { - Log.i("ReadCardInfoTask", "Use already defined encryption mode: " + lastRead_Encryption.name()); - protocol.getCard().encryptionMode = lastRead_Encryption; - } - - if (protocol.haveReadResult()) { - //already have read result (obtained while get supported encryption), only read issuer data and define offline balance - protocol.parseReadResult(); - protocol.run_ReadOrWriteIssuerDataAndDefineOfflineBalance(); - mNotifications.OnReadProgress(protocol, 60); - PINStorage.setLastUsedPIN(protocol.getCard().getPIN()); - } else { - //don't have read result - may be don't get supported encryption on this try, need encryption or need another PIN - if (lastRead_Encryption == null) { - // we try get supported encryption on this time - lastRead_Encryption = protocol.getCard().encryptionMode; - if (protocol.getCard().encryptionMode == TangemCard.EncryptionMode.None) { - // default pin not accepted - lastRead_UnsuccessfullPINs.add(PINStorage.getDefaultPIN()); - } - } - - boolean pinFound = false; - for (String PIN : PINStorage.getPINs()) { - Log.e("ReadCardInfoTask", "PIN: " + PIN); - - boolean skipPin = false; - for (int i = 0; i < lastRead_UnsuccessfullPINs.size(); i++) { - if (lastRead_UnsuccessfullPINs.get(i).equals(PIN)) { - skipPin = true; - break; - } - } - - if (skipPin) { - Log.e("ReadCardInfoTask", "Skip PIN - already checked before"); - continue; - } - - try { - protocol.setPIN(PIN); - if (protocol.getCard().encryptionMode != TangemCard.EncryptionMode.None) { - protocol.CreateProtocolKey(); - } - protocol.run_Read(); - mNotifications.OnReadProgress(protocol, 60); - PINStorage.setLastUsedPIN(PIN); - pinFound = true; - protocol.getCard().setPIN(PIN); - break; - } catch (CardProtocol.TangemException_InvalidPIN e) { - Log.e(TAG, e.getMessage()); - lastRead_UnsuccessfullPINs.add(PIN); - } - } - if (!pinFound) { - throw new CardProtocol.TangemException_InvalidPIN("No valid PIN found!"); - } - } - - protocol.run_CheckPIN2isDefault(); - - } catch (Exception e) { - e.printStackTrace(); - protocol.setError(e); - - } finally { - Log.i("ReadCardInfoTask", "[-- Finish read card info --]"); - mNotifications.OnReadFinish(protocol); - } - } finally { - mNfcManager.ignoreTag(mIsoDep.getTag()); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - void cancel(Boolean AllowInterrupt) { - try { - if (this.isAlive()) { - isCancelled = true; - join(500); - } - if (this.isAlive() && AllowInterrupt) { - interrupt(); - mNotifications.OnReadCancel(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - } + private String lastRead_UID = ""; private class RateInfoTask extends ExchangeTask { protected void onPostExecute(List requests) { @@ -653,6 +507,8 @@ public class Main extends Fragment implements NfcAdapter.ReaderCallback, CardLis } } else if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_ENTER_PIN_ACTIVITY) { if (lastTag != null) onTagDiscovered(lastTag); + if (BuildConfig.DEBUG) + Toast.makeText(getContext(), "onNFCReaderCallback 3", Toast.LENGTH_SHORT).show(); } } @@ -683,7 +539,7 @@ public class Main extends Fragment implements NfcAdapter.ReaderCallback, CardLis } lastTag = tag; - readCardInfoTask = new ReadCardInfoTask(isoDep, this); + readCardInfoTask = new ReadCardInfoTask(getActivity(), mNfcManager, lastRead_UID, isoDep, this); readCardInfoTask.start(); Log.i(TAG, "onTagDiscovered " + Arrays.toString(tag.getId())); @@ -721,17 +577,7 @@ public class Main extends Fragment implements NfcAdapter.ReaderCallback, CardLis startActivityForResult(intent, REQUEST_CODE_SHOW_CARD_ACTIVITY); } - @Override - public void doClean() { - mCardListAdapter.clearCards(); - slCardUIDs.clear(); - for (RequestWalletInfoTask rt : requestTasks) { - rt.cancel(true); - } - lastRead_UID = ""; - } - public void OnReadStart(CardProtocol cardProtocol) { progressBar.post(() -> { progressBar.setVisibility(View.VISIBLE); @@ -739,10 +585,12 @@ public class Main extends Fragment implements NfcAdapter.ReaderCallback, CardLis }); } + @Override public void OnReadProgress(CardProtocol protocol, final int progress) { progressBar.post(() -> progressBar.setProgress(progress)); } + @Override public void OnReadFinish(final CardProtocol cardProtocol) { readCardInfoTask = null; if (cardProtocol != null) { @@ -750,8 +598,8 @@ public class Main extends Fragment implements NfcAdapter.ReaderCallback, CardLis progressBar.post(() -> { progressBar.setProgress(100); progressBar.setProgressTintList(ColorStateList.valueOf(Color.GREEN)); -// addCard(cardProtocol.getCard()); +// addCard(cardProtocol.getCard()); Bundle cardInfo = new Bundle(); cardInfo.putString("UID", cardProtocol.getCard().getUID()); @@ -857,6 +705,16 @@ public class Main extends Fragment implements NfcAdapter.ReaderCallback, CardLis WaitSecurityDelayDialog.onReadAfterRequest(Objects.requireNonNull(getActivity())); } + @Override + public void doClean() { + mCardListAdapter.clearCards(); + slCardUIDs.clear(); + for (RequestWalletInfoTask rt : requestTasks) { + rt.cancel(true); + } + lastRead_UID = ""; + } + private void addCard(final TangemCard card) { if (mCardListAdapter != null) { Objects.requireNonNull(getActivity()).runOnUiThread(() -> { diff --git a/app/src/main/res/layout/fr_verify_card.xml b/app/src/main/res/layout/fr_verify_card.xml index 049b15bc23..27f70337c0 100644 --- a/app/src/main/res/layout/fr_verify_card.xml +++ b/app/src/main/res/layout/fr_verify_card.xml @@ -11,31 +11,6 @@ tools:context="com.tangem.presentation.fragment.VerifyCard" tools:showIn="@layout/activity_verify_card"> - - - - -