tangem-app-android-audited/app/src/main/java/com/tangem/presentation/fragment/MainActivityFragment.java
2018-05-29 16:11:22 +03:00

1058 lines
48 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.tangem.presentation.fragment;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.tangem.domain.cardReader.CardProtocol;
import com.tangem.domain.cardReader.NfcManager;
import com.tangem.domain.cardReader.Util;
import com.tangem.presentation.activity.EmptyWalletActivity;
import com.tangem.presentation.activity.LoadedWalletActivity;
import com.tangem.presentation.activity.MainActivity;
import com.tangem.presentation.activity.RequestPINActivity;
import com.tangem.wallet.Blockchain;
import com.tangem.presentation.adapter.CardListAdapter;
import com.tangem.wallet.CoinEngine;
import com.tangem.wallet.CoinEngineFactory;
import com.tangem.data.network.request.Electrum_Request;
import com.tangem.data.network.task.Electrum_Task;
import com.tangem.data.network.request.ExchangeRequest;
import com.tangem.data.network.task.ExchangeTask;
import com.tangem.wallet.Infura_Request;
import com.tangem.data.network.task.Infura_Task;
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog;
import com.tangem.wallet.PINStorage;
import com.tangem.wallet.R;
import com.tangem.wallet.SharedData;
import com.tangem.wallet.Tangem_Card;
import com.tangem.presentation.dialog.WaitSecurityDelayDialog;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
/**
* A placeholder fragment containing a simple view.
*/
public class MainActivityFragment extends Fragment implements NfcAdapter.ReaderCallback, CardListAdapter.UiCallbacks, CardProtocol.Notifications, MainActivity.OnCardsClean {
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<String> slCardUIDs = new ArrayList<>();
private static final String logTag = "MainActivityFragment";
private ProgressBar progressBar;
private CardListAdapter mCardListAdapter;
public CardListAdapter getCardListAdapter() {
return mCardListAdapter;
}
private ReadCardInfoTask readCardInfoTask;
private SwipeRefreshLayout mSwipeRefreshLayout; //TODO: tmp
List<RequestWalletInfoTask> requestTasks = new ArrayList<>();
public MainActivityFragment() {
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mCardListAdapter.onSaveInstanceState(outState);
outState.putStringArrayList("slCardUIDs", slCardUIDs);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View result = inflater.inflate(R.layout.fragment_main, container, false);
mNfcManager = new NfcManager(this.getActivity(), this);
verifyPermissions();
progressBar = result.findViewById(R.id.progressBar);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
RecyclerView rvCards = result.findViewById(R.id.lvCards);
rvCards.setLayoutManager(new LinearLayoutManager(getContext()));
mCardListAdapter = new CardListAdapter(getActivity().getLayoutInflater(), savedInstanceState, this);
rvCards.setAdapter(mCardListAdapter);
if (savedInstanceState != null && savedInstanceState.containsKey("slCardUIDs")) {
slCardUIDs = savedInstanceState.getStringArrayList("slCardUIDs");
}
// SwipeRefreshLayout
mSwipeRefreshLayout = result.findViewById(R.id.swipe_container); //TODO: tmp
if( mSwipeRefreshLayout!=null ) {
SwipeRefreshLayout.OnRefreshListener onRefreshListener = new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
//Update
// Showing refresh animation before making http call
if (requestTasks.size() > 0) return;
if (requestTasks.size() > 0) { //TODO: tmp
mSwipeRefreshLayout.setRefreshing(true);
} else {
mSwipeRefreshLayout.setRefreshing(false);
}
}
};
mSwipeRefreshLayout.setOnRefreshListener(onRefreshListener); //TODO: tmp
}
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
//Remove swiped item from list and notify the RecyclerView
int cardIndex = viewHolder.getAdapterPosition();
if (cardIndex < 0 || cardIndex >= mCardListAdapter.getItemCount()) return;
slCardUIDs.remove(mCardListAdapter.getCard(cardIndex).getUID());
if (mCardListAdapter.getCard(cardIndex).getUID() == lastRead_UID) {
lastRead_UID = "";
}
mCardListAdapter.removeCard(cardIndex);
if (mCardListAdapter.getItemCount() == 0 && getActivity().getClass() == MainActivity.class) {
((MainActivity) getActivity()).hideCleanButton();
}
}
});
itemTouchHelper.attachToRecyclerView(rvCards);
if (getActivity() instanceof MainActivity) {
((MainActivity) getActivity()).setOnCardsClean(this);
// ((MainActivity) getActivity()).setOnCreateNFCDialog(this);
((MainActivity) getActivity()).setNfcAdapterReaderCallback(this);
}
return result;
}
private void verifyPermissions() {
NfcManager.verifyPermissions(getActivity());
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
Log.e("QRScanActivity", "User hasn't granted permission to use camera");
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_REQUEST_CAMERA_PERMISSIONS);
}
}
int unsuccessReadCount = 0;
Tag lastTag = null;
@Override
public void onTagDiscovered(Tag tag) {
try {
// get IsoDep handle and run cardReader thread
final IsoDep isoDep = IsoDep.get(tag);
if (isoDep == null) {
throw new CardProtocol.TangemException(getString(R.string.wrong_tag_err));
}
byte UID[] = tag.getId();
String sUID = Util.byteArrayToHexString(UID);
if (slCardUIDs.indexOf(sUID) != -1) {
Log.d(logTag, "Repeat UID: " + sUID);
mNfcManager.IgnoreTag(isoDep.getTag());
return;
} else {
Log.v(logTag, "UID: " + sUID);
}
// Log.e(logTag,"setTimeout("+String.valueOf(1000 + 3000 * unsuccessReadCount)+")");
if (unsuccessReadCount < 2) {
isoDep.setTimeout(2000 + 5000 * unsuccessReadCount);
} else {
isoDep.setTimeout(90000);
}
lastTag = tag;
readCardInfoTask = new ReadCardInfoTask(isoDep, this);
readCardInfoTask.start();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onResume() {
super.onResume();
mNfcManager.onResume();
}
@Override
public void onPause() {
mNfcManager.onPause();
if (readCardInfoTask != null) {
readCardInfoTask.cancel(true);
}
super.onPause();
}
@Override
public void onStop() {
// dismiss enable NFC dialog
mNfcManager.onStop();
if (readCardInfoTask != null) {
readCardInfoTask.cancel(true);
}
for (RequestWalletInfoTask rt : requestTasks) {
rt.cancel(true);
}
super.onStop();
}
public void refreshCard(Tangem_Card card) {
CoinEngine engine = CoinEngineFactory.Create(card.getBlockchain());
if (card.getBlockchain() == Blockchain.Ethereum || card.getBlockchain() == Blockchain.EthereumTestNet) {
ETHRequestTask task = new ETHRequestTask(card.getBlockchain());
Infura_Request req = Infura_Request.GetBalance(card.getWallet());
req.setID(67);
req.setBlockchain(card.getBlockchain());
Infura_Request reqNonce = Infura_Request.GetOutTransactionCount(card.getWallet());
reqNonce.setID(67);
reqNonce.setBlockchain(card.getBlockchain());
task.execute(req, reqNonce);
RateInfoTask taskRate = new RateInfoTask();
ExchangeRequest rate = ExchangeRequest.GetRate(card.getWallet(), "ethereum", "ethereum");
taskRate.execute(rate);
} else if (card.getBlockchain() == Blockchain.BitcoinTestNet || card.getBlockchain() == Blockchain.Bitcoin) {
SharedData data = new SharedData(SharedData.COUNT_REQUEST);
for (int i = 0; i < data.allRequest; ++i) {
String nodeAddress = engine.GetNextNode(card);
int nodePort = engine.GetNextNodePort(card);
RequestWalletInfoTask connectTaskEx = new RequestWalletInfoTask(nodeAddress, nodePort, data);
connectTaskEx.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Electrum_Request.CheckBalance(card.getWallet()));
}
String nodeAddress = engine.GetNode(card);
int nodePort = engine.GetNodePort(card);
RequestWalletInfoTask task = new RequestWalletInfoTask(nodeAddress, nodePort);
if( mSwipeRefreshLayout!=null ) mSwipeRefreshLayout.setRefreshing(true); //TODO: tmp
requestTasks.add(task);
task.execute(Electrum_Request.ListUnspent(card.getWallet()), Electrum_Request.ListHistory(card.getWallet()));
RateInfoTask taskRate = new RateInfoTask();
ExchangeRequest rate = ExchangeRequest.GetRate(card.getWallet(), "bitcoin", "bitcoin");
taskRate.execute(rate);
}
else if (card.getBlockchain() == Blockchain.BitcoinCashTestNet || card.getBlockchain() == Blockchain.BitcoinCash) {
SharedData data = new SharedData(SharedData.COUNT_REQUEST);
for (int i = 0; i < data.allRequest; ++i) {
String nodeAddress = engine.GetNextNode(card);
int nodePort = engine.GetNextNodePort(card);
RequestWalletInfoTask connectTaskEx = new RequestWalletInfoTask(nodeAddress, nodePort, data);
connectTaskEx.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Electrum_Request.CheckBalance(card.getWallet()));
}
String nodeAddress = engine.GetNode(card);
int nodePort = engine.GetNodePort(card);
RequestWalletInfoTask task = new RequestWalletInfoTask(nodeAddress, nodePort);
if( mSwipeRefreshLayout!=null ) mSwipeRefreshLayout.setRefreshing(true); //TODO: tmp
requestTasks.add(task);
task.execute(Electrum_Request.ListUnspent(card.getWallet()), Electrum_Request.ListHistory(card.getWallet()));
RateInfoTask taskRate = new RateInfoTask();
ExchangeRequest rate = ExchangeRequest.GetRate(card.getWallet(), "bitcoin-cash", "bitcoin-cash");
taskRate.execute(rate);
}else if (card.getBlockchain() == Blockchain.Token) {
ETHRequestTask updateETH = new ETHRequestTask(card.getBlockchain());
Infura_Request reqETH = Infura_Request.GetTokenBalance(card.getWallet(), engine.GetContractAddress(card), engine.GetTokenDecimals(card));
reqETH.setID(67);
reqETH.setBlockchain(card.getBlockchain());
Infura_Request reqBalance = Infura_Request.GetBalance(card.getWallet());
reqBalance.setID(67);
reqBalance.setBlockchain(card.getBlockchain());
RateInfoTask taskRate = new RateInfoTask();
ExchangeRequest rate = ExchangeRequest.GetRate(card.getWallet(), "basic-attention-token", "ethereum");
taskRate.execute(rate);
Infura_Request reqNonce = Infura_Request.GetOutTransactionCount(card.getWallet());
reqNonce.setID(67);
reqNonce.setBlockchain(card.getBlockchain());
updateETH.execute(reqETH, reqNonce, reqBalance);
}
}
public void addCard(final Tangem_Card card) {
if (mCardListAdapter != null) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
unsuccessReadCount = 0;
slCardUIDs.add(0, card.getUID());
mCardListAdapter.addCard(card);
CoinEngine engine = CoinEngineFactory.Create(card.getBlockchain());
if (card.getStatus() == Tangem_Card.Status.Loaded) {
if (card.getBlockchain() == Blockchain.Ethereum || card.getBlockchain() == Blockchain.EthereumTestNet) {
ETHRequestTask task = new ETHRequestTask(card.getBlockchain());
Infura_Request req = Infura_Request.GetBalance(card.getWallet());
req.setID(67);
req.setBlockchain(card.getBlockchain());
Infura_Request reqNonce = Infura_Request.GetOutTransactionCount(card.getWallet());
reqNonce.setID(67);
reqNonce.setBlockchain(card.getBlockchain());
task.execute(req, reqNonce);
RateInfoTask taskRate = new RateInfoTask();
ExchangeRequest rate = ExchangeRequest.GetRate(card.getWallet(), "ethereum", "ethereum");
taskRate.execute(rate);
} else if (card.getBlockchain() == Blockchain.BitcoinTestNet || card.getBlockchain() == Blockchain.Bitcoin) {
SharedData data = new SharedData(SharedData.COUNT_REQUEST);
for (int i = 0; i < data.allRequest; ++i) {
String nodeAddress = engine.GetNextNode(card);
int nodePort = engine.GetNextNodePort(card);
RequestWalletInfoTask connectTaskEx = new RequestWalletInfoTask(nodeAddress, nodePort, data);
connectTaskEx.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Electrum_Request.CheckBalance(card.getWallet()));
}
String nodeAddress = engine.GetNode(card);
int nodePort = engine.GetNodePort(card);
RequestWalletInfoTask task = new RequestWalletInfoTask(nodeAddress, nodePort);
if( mSwipeRefreshLayout!=null ) mSwipeRefreshLayout.setRefreshing(true); //TODO: tmp
requestTasks.add(task);
task.execute(Electrum_Request.ListUnspent(card.getWallet()), Electrum_Request.ListHistory(card.getWallet()));
RateInfoTask taskRate = new RateInfoTask();
ExchangeRequest rate = ExchangeRequest.GetRate(card.getWallet(), "bitcoin", "bitcoin");
taskRate.execute(rate);
}else if (card.getBlockchain() == Blockchain.BitcoinCashTestNet || card.getBlockchain() == Blockchain.BitcoinCash) {
SharedData data = new SharedData(SharedData.COUNT_REQUEST);
for (int i = 0; i < data.allRequest; ++i) {
String nodeAddress = engine.GetNextNode(card);
int nodePort = engine.GetNextNodePort(card);
RequestWalletInfoTask connectTaskEx = new RequestWalletInfoTask(nodeAddress, nodePort, data);
connectTaskEx.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Electrum_Request.CheckBalance(card.getWallet()));
}
String nodeAddress = engine.GetNode(card);
int nodePort = engine.GetNodePort(card);
RequestWalletInfoTask task = new RequestWalletInfoTask(nodeAddress, nodePort);
if( mSwipeRefreshLayout!=null ) mSwipeRefreshLayout.setRefreshing(true); //TODO: tmp
requestTasks.add(task);
task.execute(Electrum_Request.ListUnspent(card.getWallet()), Electrum_Request.ListHistory(card.getWallet()));
RateInfoTask taskRate = new RateInfoTask();
ExchangeRequest rate = ExchangeRequest.GetRate(card.getWallet(), "bitcoin-cash", "bitcoin-cash");
taskRate.execute(rate);
}
else if (card.getBlockchain() == Blockchain.Token) {
ETHRequestTask updateETH = new ETHRequestTask(card.getBlockchain());
Infura_Request reqETH = Infura_Request.GetTokenBalance(card.getWallet(), engine.GetContractAddress(card), engine.GetTokenDecimals(card));
reqETH.setID(67);
reqETH.setBlockchain(card.getBlockchain());
Infura_Request reqBalance = Infura_Request.GetBalance(card.getWallet());
reqBalance.setID(67);
reqBalance.setBlockchain(card.getBlockchain());
RateInfoTask taskRate = new RateInfoTask();
ExchangeRequest rate = ExchangeRequest.GetRate(card.getWallet(), "basic-attention-token", "ethereum");
taskRate.execute(rate);
Infura_Request reqNonce = Infura_Request.GetOutTransactionCount(card.getWallet());
reqNonce.setID(67);
reqNonce.setBlockchain(card.getBlockchain());
updateETH.execute(reqETH, reqNonce, reqBalance);
}
}
if (getActivity().getClass() == MainActivity.class) {
((MainActivity) getActivity()).showCleanButton();
}
}
});
}
}
@Override
public void onViewCard(Bundle cardInfo) {
if( mSwipeRefreshLayout!=null ) mSwipeRefreshLayout.setRefreshing(false); //TODO: tmp
String UID = cardInfo.getString("UID");
Tangem_Card card = new Tangem_Card(UID);
card.LoadFromBundle(cardInfo.getBundle("Card"));
Intent intent;
if (card.getStatus() == Tangem_Card.Status.Empty) {
intent = new Intent(getActivity(), EmptyWalletActivity.class);
} else if (card.getStatus() == Tangem_Card.Status.Loaded) {
intent = new Intent(getActivity(), LoadedWalletActivity.class);
} else if (card.getStatus() == Tangem_Card.Status.NotPersonalized || card.getStatus() == Tangem_Card.Status.Purged) {
return;
} else {
intent = new Intent(getActivity(), LoadedWalletActivity.class);
}
intent.putExtras(cardInfo);
startActivityForResult(intent, REQUEST_CODE_SHOW_CARD_ACTIVITY);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(logTag, "ActivityResult: requestCode = " + requestCode + ", resultCode = " + resultCode);
// если пришло ОК
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_SHOW_CARD_ACTIVITY) {
if (data != null && data.getExtras().containsKey("UID")) {
final Tangem_Card card = new Tangem_Card(data.getStringExtra("UID"));
card.LoadFromBundle(data.getBundleExtra("Card"));
if (data.getStringExtra("modification").equals("delete")) {
mCardListAdapter.removeCard(card);
for (int i = 0; i < slCardUIDs.size(); i++) {
if (slCardUIDs.get(i).equals(card.getUID())) {
slCardUIDs.remove(i);
break;
}
}
if (mCardListAdapter.getItemCount() == 0 && getActivity().getClass() == MainActivity.class) {
((MainActivity) getActivity()).hideCleanButton();
}
} else if (data.getStringExtra("modification").equals("update")) {
mCardListAdapter.updateCard(card);
} else if (data.getStringExtra("modification").equals("updateAndViewCard")) {
mCardListAdapter.updateCard(card);
onViewCard(data.getExtras());
}
}
} else if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_ENTER_PIN_ACTIVITY) {
if (lastTag != null) onTagDiscovered(lastTag);
}
}
@Override
public void doClean() {
mCardListAdapter.clearCards();
slCardUIDs.clear();
for (RequestWalletInfoTask rt : requestTasks) {
rt.cancel(true);
}
lastRead_UID = "";
}
public void doEnterPIN() {
Intent intent = new Intent(getContext(), RequestPINActivity.class);
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN.toString());
startActivityForResult(intent, REQUEST_CODE_ENTER_PIN_ACTIVITY);
}
private static String lastRead_UID = "";
private static ArrayList<String> lastRead_UnsuccessfullPINs = new ArrayList<>();
private static Tangem_Card.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 == Tangem_Card.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 != Tangem_Card.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(logTag, 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();
}
}
}
public void OnReadStart(CardProtocol cardProtocol) {
progressBar.post(new Runnable() {
@Override
public void run() {
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress(5);
}
});
}
public void OnReadFinish(final CardProtocol cardProtocol) {
readCardInfoTask = null;
if (cardProtocol != null) {
if (cardProtocol.getError() == null) {
progressBar.post(new Runnable() {
@Override
public void run() {
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.GREEN));
addCard(cardProtocol.getCard());
}
});
} else {
// remove last UIDs because of error and no card read
progressBar.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getContext(), "Try to scan again", Toast.LENGTH_LONG).show();
unsuccessReadCount++;
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
slCardUIDs.remove(cardProtocol.getCard().getUID());
if (cardProtocol.getError() instanceof CardProtocol.TangemException_InvalidPIN) {
doEnterPIN();
} else if (cardProtocol.getError() instanceof CardProtocol.TangemException_ExtendedLengthNotSupported) {
if (!NoExtendedLengthSupportDialog.allreadyShowed) {
new NoExtendedLengthSupportDialog().show(getActivity().getFragmentManager(), "NoExtendedLengthSupportDialog");
}
} else {
lastTag = null;
}
}
});
}
}
progressBar.postDelayed(new Runnable() {
@Override
public void run() {
try {
progressBar.setProgress(0);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
progressBar.setVisibility(View.INVISIBLE);
} catch (Exception e) {
e.printStackTrace();
}
}
}, 500);
}
public void OnReadProgress(CardProtocol protocol, final int progress) {
progressBar.post(new Runnable() {
@Override
public void run() {
progressBar.setProgress(progress);
}
});
}
public void OnReadCancel() {
readCardInfoTask = null;
progressBar.postDelayed(new Runnable() {
@Override
public void run() {
try {
progressBar.setProgress(0);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
progressBar.setVisibility(View.INVISIBLE);
} catch (Exception e) {
e.printStackTrace();
}
}
}, 500);
}
public void OnReadWait(final int msec) {
WaitSecurityDelayDialog.OnReadWait(getActivity(), msec);
}
@Override
public void OnReadBeforeRequest(int timeout) {
WaitSecurityDelayDialog.onReadBeforeRequest(getActivity(), timeout);
}
@Override
public void OnReadAfterRequest() {
WaitSecurityDelayDialog.onReadAfterRequest(getActivity());
}
private class RequestWalletInfoTask extends Electrum_Task {
public RequestWalletInfoTask(String host, int port) {
super(host, port);
}
public RequestWalletInfoTask(String host, int port, SharedData sharedData) {
super(host, port, sharedData);
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
@Override
protected void onCancelled() {
super.onCancelled();
requestTasks.remove(this);
if ( mSwipeRefreshLayout!=null && requestTasks.size() == 0) mSwipeRefreshLayout.setRefreshing(false); //TODO: tmp
}
void FinishWithError(String wallet, String message) {
mCardListAdapter.UpdateWalletError(wallet, "Cannot obtain data from blockchain");
}
@Override
protected void onPostExecute(List<Electrum_Request> requests) {
super.onPostExecute(requests);
requestTasks.remove(this);
Log.i("RequestWalletInfoTask", "onPostExecute[" + String.valueOf(requests.size()) + "]");
CoinEngine engine = CoinEngineFactory.Create(Blockchain.Bitcoin);
for (Electrum_Request request : requests) {
try {
if (request.error == null) {
if (request.isMethod(Electrum_Request.METHOD_GetBalance)) {
try {
Long conf = request.getResult().getLong("confirmed");
Long unconf = request.getResult().getLong("unconfirmed");
if (sharedCounter != null) {
int counter = sharedCounter.requestCounter.incrementAndGet();
if (counter != 1) {
continue;
}
}
String mWalletAddress = request.getParams().getString(0);
mCardListAdapter.UpdateWalletBalance(mWalletAddress, conf, unconf, getValidationNodeDescription());
} catch (JSONException e) {
if (sharedCounter != null) {
int errCounter = sharedCounter.errorRequest.incrementAndGet();
if (errCounter == sharedCounter.allRequest) {
e.printStackTrace();
FinishWithError(request.WalletAddress, e.toString());
engine.SwitchNode(null);
}
} else {
e.printStackTrace();
FinishWithError(request.WalletAddress, e.toString());
engine.SwitchNode(null);
}
}
} else if (request.isMethod(Electrum_Request.METHOD_ListUnspent)) {
try {
String mWalletAddress = request.getParams().getString(0);
mCardListAdapter.UpdateWalletUnspent(mWalletAddress, request.getResultArray());
JSONArray unspentList = request.getResultArray();
for (int i = 0; i < unspentList.length(); i++) {
JSONObject jsUnspent = unspentList.getJSONObject(i);
Integer height = jsUnspent.getInt("height");
String hash = jsUnspent.getString("tx_hash");
if (height != -1) {
RequestWalletInfoTask task = new RequestWalletInfoTask(request.Host, request.Port);
requestTasks.add(task);
task.execute(Electrum_Request.GetHeader(mWalletAddress, String.valueOf(height)),
Electrum_Request.GetTransaction(mWalletAddress, hash));
}
}
} catch (JSONException e) {
e.printStackTrace();
FinishWithError(request.WalletAddress, e.toString());
engine.SwitchNode(null);
}
} else if (request.isMethod(Electrum_Request.METHOD_GetHistory)) {
try {
String mWalletAddress = request.getParams().getString(0);
mCardListAdapter.UpdateWalletHistory(mWalletAddress, request.getResultArray());
JSONArray historyList = request.getResultArray();
for (int i = 0; i < historyList.length(); i++) {
JSONObject jsUnspent = historyList.getJSONObject(i);
Integer height = jsUnspent.getInt("height");
String hash = jsUnspent.getString("tx_hash");
if (height != -1) {
RequestWalletInfoTask task = new RequestWalletInfoTask(request.Host, request.Port);
requestTasks.add(task);
task.execute(Electrum_Request.GetHeader(mWalletAddress, String.valueOf(height)),
Electrum_Request.GetTransaction(mWalletAddress, hash));
}
}
} catch (JSONException e) {
e.printStackTrace();
FinishWithError(request.WalletAddress, e.toString());
engine.SwitchNode(null);
}
} else if (request.isMethod(Electrum_Request.METHOD_GetHeader)) {
try {
String mWalletAddress = request.WalletAddress;
mCardListAdapter.UpdateWalletHeader(mWalletAddress, request.getResult());
} catch (JSONException e) {
e.printStackTrace();
FinishWithError(request.WalletAddress, e.toString());
engine.SwitchNode(null);
}
} else if (request.isMethod(Electrum_Request.METHOD_GetTransaction)) {
try {
Log.e("MainActivityFragment_TX", request.TxHash);
String mWalletAddress = request.WalletAddress;
String tx = request.TxHash;
String raw = request.getResultString();
Log.e("MainActivityFragment_R", raw);
mCardListAdapter.UpdateTransaction(mWalletAddress, tx, raw);
} catch (JSONException e) {
e.printStackTrace();
mCardListAdapter.UpdateWalletError(request.WalletAddress, "Cannot obtain data from blockchain");
FinishWithError(request.WalletAddress, e.toString());
engine.SwitchNode(null);
}
}
} else {
if (sharedCounter != null) {
int errCounter = sharedCounter.errorRequest.incrementAndGet();
if (errCounter >= sharedCounter.allRequest) {
FinishWithError(request.WalletAddress, request.error);
engine.SwitchNode(null);
}
} else {
FinishWithError(request.WalletAddress, request.error);
engine.SwitchNode(null);
}
}
} catch (JSONException e) {
if (sharedCounter != null) {
int errCounter = sharedCounter.errorRequest.incrementAndGet();
if (errCounter >= sharedCounter.allRequest) {
e.printStackTrace();
mCardListAdapter.UpdateWalletError(request.WalletAddress, "Cannot obtain data from blockchain");
engine.SwitchNode(null);
}
} else {
e.printStackTrace();
mCardListAdapter.UpdateWalletError(request.WalletAddress, "Cannot obtain data from blockchain");
engine.SwitchNode(null);
}
}
}
if ( mSwipeRefreshLayout!=null && requestTasks.size() == 0) mSwipeRefreshLayout.setRefreshing(false); //TODO: tmp
}
}
private class ETHRequestTask extends Infura_Task {
ETHRequestTask(Blockchain blockchain) {
super(blockchain);
}
void FinishWithError(String wallet, String message) {
mCardListAdapter.UpdateWalletError(wallet, "Cannot obtain data from blockchain");
}
@Override
protected void onPostExecute(List<Infura_Request> requests) {
super.onPostExecute(requests);
for (Infura_Request request : requests) {
try {
if (request.error == null) {
if (request.isMethod(Infura_Request.METHOD_ETH_GetBalance)) {
try {
String mWalletAddress = request.getParams().getString(0);
String balanceCap = request.getResultString();
balanceCap = balanceCap.substring(2);
BigInteger l = new BigInteger(balanceCap, 16);
BigInteger d = l.divide(new BigInteger("1000000000000000000", 10));
Long balance = d.longValue();
if (request.getBlockchain() != Blockchain.Token)
mCardListAdapter.UpdateWalletBalance(mWalletAddress, balance, l.toString(10), getValidationNodeDescription());
mCardListAdapter.UpdateWalletBalanceOnlyAlter(mWalletAddress, l.toString(10));
} catch (JSONException e) {
e.printStackTrace();
FinishWithError(request.WalletAddress, e.toString());
}
} else if (request.isMethod(Infura_Request.METHOD_ETH_Call)) {
try {
String mWalletAddress = request.WalletAddress;
String balanceCap = request.getResultString();
balanceCap = balanceCap.substring(2);
BigInteger l = new BigInteger(balanceCap, 16);
Long balance = l.longValue();
if (l.compareTo(BigInteger.ZERO) == 0) {
mCardListAdapter.UpdateWalletBlockchain(mWalletAddress, Blockchain.Ethereum);
mCardListAdapter.AddWalletBlockchainNameToken(mWalletAddress);
Tangem_Card card = mCardListAdapter.getCardByWallet(request.WalletAddress);
if (card != null) {
refreshCard(card);
}
return;
}
mCardListAdapter.UpdateWalletBalance(mWalletAddress, balance, l.toString(10), getValidationNodeDescription());
} catch (JSONException e) {
e.printStackTrace();
FinishWithError(request.WalletAddress, e.toString());
} catch (Exception e) {
e.printStackTrace();
FinishWithError(request.WalletAddress, e.toString());
}
} else if (request.isMethod(Infura_Request.METHOD_ETH_GetOutTransactionCount)) {
try {
String mWalletAddress = request.getParams().getString(0);
String nonce = request.getResultString();
nonce = nonce.substring(2);
BigInteger count = new BigInteger(nonce, 16);
mCardListAdapter.UpdateWalletCoutConfirmTx(mWalletAddress, count);
} catch (JSONException e) {
e.printStackTrace();
FinishWithError(request.WalletAddress, e.toString());
}
}
} else {
FinishWithError(request.WalletAddress, request.error);
}
} catch (JSONException e) {
e.printStackTrace();
FinishWithError(request.WalletAddress, e.toString());
}
}
}
}
private class RateInfoTask extends ExchangeTask {
protected void onPostExecute(List<ExchangeRequest> requests) {
super.onPostExecute(requests);
for (ExchangeRequest request : requests) {
if (request.error == null) {
try {
JSONArray arr = request.getAnswerList();
for (int i = 0; i < arr.length(); ++i) {
JSONObject obj = arr.getJSONObject(i);
String currency = obj.getString("id");
boolean stop = false;
boolean stopAlter = false;
if (currency.equals(request.currency)) {
String usd = obj.getString("price_usd");
Float rate = Float.valueOf(usd);
mCardListAdapter.UpdateRate(request.WalletAddress, rate);
stop = true;
}
if (currency.equals(request.currencyAlter)) {
String usd = obj.getString("price_usd");
Float rate = Float.valueOf(usd);
mCardListAdapter.UpdateRateAlter(request.WalletAddress, rate);
stopAlter = true;
}
if (stop && stopAlter) {
break;
}
}
//mCardListAdapter.UpdateWalletBalance(mWalletAddress, balance, l.toString(10));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
}
}