Updated on 2026-08-14

This commit is contained in:
Tangem 2018-05-29 13:28:36 +03:00
parent 0374157cad
commit 8c17a8d4f0
48 changed files with 3490 additions and 3417 deletions

View file

@ -0,0 +1,4 @@
package com.tangem.domain;
public class Logic {
}

View file

@ -0,0 +1,4 @@
package com.tangem.presentation;
public class Screen {
}

View file

@ -1,122 +1,126 @@
package com.tangem.wallet;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
public class CardInfoActivity extends AppCompatActivity implements WalletInfoFragment.OnFragmentInteractionListener {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
private Tangem_Card mCard;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_card_info);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
String UID = getIntent().getStringExtra("UID");
mCard = new Tangem_Card(UID);
mCard.LoadFromBundle(getIntent().getBundleExtra("Card"));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_card_info, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
if (position == 0) {
return WalletInfoFragment.newInstance(mCard);
} /*else if (position == 1) {
return WalletUnspentFragment.newInstance(mCard);
} else if (position == 2) {
return WalletHistoryFragment.newInstance(mCard);
}*/
return null;
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Wallet info";
case 1:
return "Unspent";
case 2:
return "History";
}
return null;
}
}
}
package com.tangem.presentation.activity;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import com.tangem.wallet.R;
import com.tangem.wallet.Tangem_Card;
import com.tangem.wallet.WalletInfoFragment;
public class CardInfoActivity extends AppCompatActivity implements WalletInfoFragment.OnFragmentInteractionListener {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
private Tangem_Card mCard;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_card_info);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
String UID = getIntent().getStringExtra("UID");
mCard = new Tangem_Card(UID);
mCard.LoadFromBundle(getIntent().getBundleExtra("Card"));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_card_info, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
if (position == 0) {
return WalletInfoFragment.newInstance(mCard);
} /*else if (position == 1) {
return WalletUnspentFragment.newInstance(mCard);
} else if (position == 2) {
return WalletHistoryFragment.newInstance(mCard);
}*/
return null;
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Wallet info";
case 1:
return "Unspent";
case 2:
return "History";
}
return null;
}
}
}

View file

@ -1,330 +1,334 @@
package com.tangem.wallet;
import android.app.Activity;
import android.content.Intent;
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.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.NfcManager;
import com.tangem.cardReader.Util;
public class CreateNewWalletActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback, CardProtocol.Notifications {
public static final int RESULT_INVALID_PIN = Activity.RESULT_FIRST_USER;
private Tangem_Card mCard;
private TextView tvCardID;
private NfcManager mNfcManager;
private static final String logTag = "CreateNewActivity";
private ProgressBar progressBar;
private CreateNewWalletTask createNewWalletTask;
private boolean lastReadSuccess = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_new_wallet);
MainActivity.commonInit(getApplicationContext());
mCard = new Tangem_Card(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
tvCardID = (TextView) findViewById(R.id.tvCardID);
tvCardID.setText(mCard.getCIDDescription());
mNfcManager = new NfcManager(this, this);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
progressBar.setVisibility(View.INVISIBLE);
}
@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);
Log.v(logTag, "UID: " + sUID);
if (sUID.equals(mCard.getUID())) {
if (lastReadSuccess) {
isoDep.setTimeout(mCard.getPauseBeforePIN2() + 5000);
} else {
isoDep.setTimeout(mCard.getPauseBeforePIN2() + 65000);
}
createNewWalletTask = new CreateNewWalletTask(isoDep, this);
createNewWalletTask.start();
} else {
Log.d(logTag, "Mismatch card UID (" + sUID + " instead of " + mCard.getUID() + ")");
mNfcManager.IgnoreTag(isoDep.getTag());
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onResume() {
super.onResume();
mNfcManager.onResume();
}
@Override
public void onPause() {
mNfcManager.onPause();
if (createNewWalletTask != null) {
createNewWalletTask.cancel(true);
}
super.onPause();
}
@Override
public void onStop() {
// dismiss enable NFC dialog
mNfcManager.onStop();
if (createNewWalletTask != null) {
createNewWalletTask.cancel(true);
}
super.onStop();
}
// @Override
// public Dialog CreateNFCDialog(int id, AlertDialogWrapper.Builder builder, LayoutInflater li) {
// return mNfcManager.ShowNFCEnableDialog(); //onCreateDialog(id, builder, li);
// }
private class CreateNewWalletTask extends Thread {
IsoDep mIsoDep;
CardProtocol.Notifications mNotifications;
private boolean isCancelled = false;
public CreateNewWalletTask(IsoDep isoDep, CardProtocol.Notifications notifications) {
mIsoDep = isoDep;
mNotifications = notifications;
}
@Override
public void run() {
if (mIsoDep == null) {
return;
}
CardProtocol protocol = new CardProtocol(getBaseContext(), mIsoDep, mCard, mNotifications);
mNotifications.OnReadStart(protocol);
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 {
mNotifications.OnReadProgress(protocol, 5);
Log.i("CreateNewWalletTask", "[-- Start create new wallet --]");
if (isCancelled) return;
protocol.run_VerifyCard();
Log.i("CreateNewWalletTask", "Manufacturer: " + protocol.getCard().getManufacturer().getOfficialName());
mNotifications.OnReadProgress(protocol, 30);
if (isCancelled) return;
// if (mCard.getPauseBeforePIN2() > 0) {
// mNotifications.OnReadWait(mCard.getPauseBeforePIN2());
// }
// try {
protocol.run_CreateWallet(PINStorage.getPIN2());
// } finally {
// mNotifications.OnReadWait(0);
// }
mNotifications.OnReadProgress(protocol, 60);
if (isCancelled) return;
protocol.run_Read();
} finally {
mNfcManager.IgnoreTag(mIsoDep.getTag());
}
} catch (Exception e) {
e.printStackTrace();
protocol.setError(e);
} finally {
Log.i("CreateNewWalletTask", "[-- Finish create new wallet --]");
mNotifications.OnReadFinish(protocol);
}
}
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();
}
}
}
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) {
createNewWalletTask = 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));
Intent intent = new Intent();
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
setResult(Activity.RESULT_OK, intent);
finish();
}
});
} else {
lastReadSuccess = false;
if (cardProtocol.getError() instanceof CardProtocol.TangemException_InvalidPIN) {
progressBar.post(new Runnable() {
@Override
public void run() {
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
}
});
progressBar.postDelayed(new Runnable() {
@Override
public void run() {
try {
progressBar.setProgress(0);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
progressBar.setVisibility(View.INVISIBLE);
Intent intent = new Intent();
intent.putExtra("message", "Cannot create wallet. Make sure you enter correct PIN2!");
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
setResult(RESULT_INVALID_PIN, intent);
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}, 500);
return;
} else {
progressBar.post(new Runnable() {
@Override
public void run() {
if (cardProtocol.getError() instanceof CardProtocol.TangemException_ExtendedLengthNotSupported) {
if (!NoExtendedLengthSupportDialog.allreadyShowed) {
new NoExtendedLengthSupportDialog().show(getFragmentManager(), "NoExtendedLengthSupportDialog");
}
} else {
Toast.makeText(getBaseContext(), "Try to scan again", Toast.LENGTH_LONG).show();
}
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
}
});
}
}
}
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() {
createNewWalletTask = 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);
}
@Override
public void OnReadWait(final int msec) {
WaitSecurityDelayDialog.OnReadWait(this, msec);
}
@Override
public void OnReadBeforeRequest(int timeout) {
WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout);
}
@Override
public void OnReadAfterRequest() {
WaitSecurityDelayDialog.onReadAfterRequest(this);
}
}
package com.tangem.presentation.activity;
import android.app.Activity;
import android.content.Intent;
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.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.NfcManager;
import com.tangem.cardReader.Util;
import com.tangem.wallet.NoExtendedLengthSupportDialog;
import com.tangem.wallet.PINStorage;
import com.tangem.wallet.R;
import com.tangem.wallet.Tangem_Card;
import com.tangem.wallet.WaitSecurityDelayDialog;
public class CreateNewWalletActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback, CardProtocol.Notifications {
public static final int RESULT_INVALID_PIN = Activity.RESULT_FIRST_USER;
private Tangem_Card mCard;
private TextView tvCardID;
private NfcManager mNfcManager;
private static final String logTag = "CreateNewActivity";
private ProgressBar progressBar;
private CreateNewWalletTask createNewWalletTask;
private boolean lastReadSuccess = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_new_wallet);
MainActivity.commonInit(getApplicationContext());
mCard = new Tangem_Card(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
tvCardID = (TextView) findViewById(R.id.tvCardID);
tvCardID.setText(mCard.getCIDDescription());
mNfcManager = new NfcManager(this, this);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
progressBar.setVisibility(View.INVISIBLE);
}
@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);
Log.v(logTag, "UID: " + sUID);
if (sUID.equals(mCard.getUID())) {
if (lastReadSuccess) {
isoDep.setTimeout(mCard.getPauseBeforePIN2() + 5000);
} else {
isoDep.setTimeout(mCard.getPauseBeforePIN2() + 65000);
}
createNewWalletTask = new CreateNewWalletTask(isoDep, this);
createNewWalletTask.start();
} else {
Log.d(logTag, "Mismatch card UID (" + sUID + " instead of " + mCard.getUID() + ")");
mNfcManager.IgnoreTag(isoDep.getTag());
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onResume() {
super.onResume();
mNfcManager.onResume();
}
@Override
public void onPause() {
mNfcManager.onPause();
if (createNewWalletTask != null) {
createNewWalletTask.cancel(true);
}
super.onPause();
}
@Override
public void onStop() {
// dismiss enable NFC dialog
mNfcManager.onStop();
if (createNewWalletTask != null) {
createNewWalletTask.cancel(true);
}
super.onStop();
}
// @Override
// public Dialog CreateNFCDialog(int id, AlertDialogWrapper.Builder builder, LayoutInflater li) {
// return mNfcManager.ShowNFCEnableDialog(); //onCreateDialog(id, builder, li);
// }
private class CreateNewWalletTask extends Thread {
IsoDep mIsoDep;
CardProtocol.Notifications mNotifications;
private boolean isCancelled = false;
public CreateNewWalletTask(IsoDep isoDep, CardProtocol.Notifications notifications) {
mIsoDep = isoDep;
mNotifications = notifications;
}
@Override
public void run() {
if (mIsoDep == null) {
return;
}
CardProtocol protocol = new CardProtocol(getBaseContext(), mIsoDep, mCard, mNotifications);
mNotifications.OnReadStart(protocol);
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 {
mNotifications.OnReadProgress(protocol, 5);
Log.i("CreateNewWalletTask", "[-- Start create new wallet --]");
if (isCancelled) return;
protocol.run_VerifyCard();
Log.i("CreateNewWalletTask", "Manufacturer: " + protocol.getCard().getManufacturer().getOfficialName());
mNotifications.OnReadProgress(protocol, 30);
if (isCancelled) return;
// if (mCard.getPauseBeforePIN2() > 0) {
// mNotifications.OnReadWait(mCard.getPauseBeforePIN2());
// }
// try {
protocol.run_CreateWallet(PINStorage.getPIN2());
// } finally {
// mNotifications.OnReadWait(0);
// }
mNotifications.OnReadProgress(protocol, 60);
if (isCancelled) return;
protocol.run_Read();
} finally {
mNfcManager.IgnoreTag(mIsoDep.getTag());
}
} catch (Exception e) {
e.printStackTrace();
protocol.setError(e);
} finally {
Log.i("CreateNewWalletTask", "[-- Finish create new wallet --]");
mNotifications.OnReadFinish(protocol);
}
}
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();
}
}
}
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) {
createNewWalletTask = 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));
Intent intent = new Intent();
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
setResult(Activity.RESULT_OK, intent);
finish();
}
});
} else {
lastReadSuccess = false;
if (cardProtocol.getError() instanceof CardProtocol.TangemException_InvalidPIN) {
progressBar.post(new Runnable() {
@Override
public void run() {
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
}
});
progressBar.postDelayed(new Runnable() {
@Override
public void run() {
try {
progressBar.setProgress(0);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
progressBar.setVisibility(View.INVISIBLE);
Intent intent = new Intent();
intent.putExtra("message", "Cannot create wallet. Make sure you enter correct PIN2!");
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
setResult(RESULT_INVALID_PIN, intent);
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}, 500);
return;
} else {
progressBar.post(new Runnable() {
@Override
public void run() {
if (cardProtocol.getError() instanceof CardProtocol.TangemException_ExtendedLengthNotSupported) {
if (!NoExtendedLengthSupportDialog.allreadyShowed) {
new NoExtendedLengthSupportDialog().show(getFragmentManager(), "NoExtendedLengthSupportDialog");
}
} else {
Toast.makeText(getBaseContext(), "Try to scan again", Toast.LENGTH_LONG).show();
}
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
}
});
}
}
}
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() {
createNewWalletTask = 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);
}
@Override
public void OnReadWait(final int msec) {
WaitSecurityDelayDialog.OnReadWait(this, msec);
}
@Override
public void OnReadBeforeRequest(int timeout) {
WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout);
}
@Override
public void OnReadAfterRequest() {
WaitSecurityDelayDialog.onReadAfterRequest(this);
}
}

View file

@ -1,356 +1,361 @@
package com.tangem.wallet;
import android.app.Activity;
import android.content.Intent;
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.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.NfcManager;
import com.tangem.cardReader.Util;
public class EmptyWalletActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback, CardProtocol.Notifications {
private static final int REQUEST_CODE_CREATE_NEW_WALLET_ACTIVITY = 2;
private static final int REQUEST_CODE_REQUEST_PIN2 = 3;
private static final int REQUEST_CODE_VERIFY_CARD = 4;
Tangem_Card mCard;
TextView tvCardID, tvIssuer, tvIssuerData, tvBlockchain;
ProgressBar progressBar;
ImageView ivBlockchain, ivPIN, ivPIN2orSecurityDelay, ivDeveloperVersion;
private NfcManager mNfcManager;
private final String logTag = "EmptyWalletActivity";
private boolean lastReadSuccess = true;
private VerifyCardTask verifyCardTask = null;
private int requestPIN2Count = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_empty_wallet);
MainActivity.commonInit(getApplicationContext());
mNfcManager = new NfcManager(this, this);
mCard = new Tangem_Card(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
tvCardID = findViewById(R.id.tvCardID);
tvCardID.setText(mCard.getCIDDescription());
tvIssuer = findViewById(R.id.tvIssuer);
tvIssuerData = findViewById(R.id.tvIssuerData);
tvBlockchain = findViewById(R.id.tvBlockchain);
tvIssuer.setText(mCard.getIssuerDescription());
tvIssuerData.setText(mCard.getIssuerDataDescription());
//tvBlockchain.setText(mCard.getBlockchain().getOfficialName());
tvBlockchain.setText(mCard.getBlockchainName());
progressBar = findViewById(R.id.progressBar);
ivBlockchain = findViewById(R.id.imgBlockchain);
ivPIN = findViewById(R.id.imgPIN);
ivPIN2orSecurityDelay = findViewById(R.id.imgPIN2orSecurityDelay);
ivDeveloperVersion = findViewById(R.id.imgDeveloperVersion);
ivBlockchain.setImageResource(mCard.getBlockchain().getImageResource(this, mCard.getTokenSymbol()));
if (mCard.useDefaultPIN1()) {
ivPIN.setImageResource(R.drawable.unlock_pin1);
ivPIN.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(EmptyWalletActivity.this, "This banknote is protected by default PIN1 code", Toast.LENGTH_LONG).show();
}
});
} else {
ivPIN.setImageResource(R.drawable.lock_pin1);
ivPIN.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(EmptyWalletActivity.this, "This banknote is protected by user's PIN1 code", Toast.LENGTH_LONG).show();
}
});
}
if (mCard.getPauseBeforePIN2() > 0 && (mCard.useDefaultPIN2() || !mCard.useSmartSecurityDelay())) {
ivPIN2orSecurityDelay.setImageResource(R.drawable.timer);
ivPIN2orSecurityDelay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(EmptyWalletActivity.this, String.format("This banknote will enforce %.0f seconds security delay for all operations requiring PIN2 code", mCard.getPauseBeforePIN2() / 1000.0), Toast.LENGTH_LONG).show();
}
});
} else if (mCard.useDefaultPIN2()) {
ivPIN2orSecurityDelay.setImageResource(R.drawable.unlock_pin2);
ivPIN2orSecurityDelay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(EmptyWalletActivity.this, "This banknote is protected by default PIN2 code", Toast.LENGTH_LONG).show();
}
});
} else {
ivPIN2orSecurityDelay.setImageResource(R.drawable.lock_pin2);
ivPIN2orSecurityDelay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(EmptyWalletActivity.this, "This banknote is protected by user's PIN2 code", Toast.LENGTH_LONG).show();
}
});
}
if (mCard.useDevelopersFirmware()) {
ivDeveloperVersion.setImageResource(R.drawable.ic_developer_version);
ivDeveloperVersion.setVisibility(View.VISIBLE);
ivDeveloperVersion.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(EmptyWalletActivity.this, "Unlocked banknote, only for development use", Toast.LENGTH_LONG).show();
}
});
} else {
ivDeveloperVersion.setVisibility(View.INVISIBLE);
}
Button btnNewWallet = findViewById(R.id.btnNewWallet);
btnNewWallet.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//CreateSelectBlockchainDialog();
requestPIN2Count = 0;
Intent intent = new Intent(getBaseContext(), RequestPINActivity.class);
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN2.toString());
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2);
}
});
if (getIntent().getExtras().containsKey(NfcAdapter.EXTRA_TAG)) {
Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tag != null) {
onTagDiscovered(tag);
}
}
}
private void doCreateNewWallet() {
Intent intent = new Intent(this, CreateNewWalletActivity.class);
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
// intent.putExtra("newPIN",mCard.getPIN());
// intent.putExtra("newPIN2","12345678");
startActivityForResult(intent, REQUEST_CODE_CREATE_NEW_WALLET_ACTIVITY);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_CREATE_NEW_WALLET_ACTIVITY) {
if (resultCode == Activity.RESULT_OK) {
if (data != null) {
data.putExtra("modification", "updateAndViewCard");
data.putExtra("updateDelay", 0);
setResult(Activity.RESULT_OK, data);
}
finish();
} else {
if (data != null && data.getExtras().containsKey("UID") && data.getExtras().containsKey("Card")) {
Tangem_Card updatedCard = new Tangem_Card(data.getStringExtra("UID"));
updatedCard.LoadFromBundle(data.getBundleExtra("Card"));
mCard = updatedCard;
}
if (resultCode == CreateNewWalletActivity.RESULT_INVALID_PIN && requestPIN2Count < 2) {
requestPIN2Count++;
Intent intent = new Intent(getBaseContext(), RequestPINActivity.class);
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN2.toString());
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2);
return;
}
}
setResult(resultCode, data);
finish();
} else if (requestCode == REQUEST_CODE_REQUEST_PIN2) {
if (resultCode == Activity.RESULT_OK) {
doCreateNewWallet();
}
}
}
@Override
public void onTagDiscovered(Tag tag) {
try {
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 (!mCard.getUID().equals(sUID)) {
Log.d(logTag, "Invalid UID: " + sUID);
mNfcManager.IgnoreTag(isoDep.getTag());
return;
} else {
Log.v(logTag, "UID: " + sUID);
}
if (lastReadSuccess) {
isoDep.setTimeout(1000);
} else {
isoDep.setTimeout(65000);
}
//lastTag = tag;
verifyCardTask = new VerifyCardTask(this, mCard, mNfcManager, isoDep, this);
verifyCardTask.start();
} 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) {
verifyCardTask = 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));
Intent intent = new Intent(EmptyWalletActivity.this, VerifyCardActivity.class);
// TODO обновить карту mCard
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
startActivityForResult(intent, REQUEST_CODE_VERIFY_CARD);
//addCard(cardProtocol.getCard());
}
});
} else {
// remove last UIDs because of error and no card read
progressBar.post(new Runnable() {
@Override
public void run() {
lastReadSuccess = false;
if (cardProtocol.getError() instanceof CardProtocol.TangemException_ExtendedLengthNotSupported) {
if (!NoExtendedLengthSupportDialog.allreadyShowed) {
new NoExtendedLengthSupportDialog().show(getFragmentManager(), "NoExtendedLengthSupportDialog");
}
} else {
Toast.makeText(EmptyWalletActivity.this, "Try to scan again", Toast.LENGTH_LONG).show();
}
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
}
});
}
}
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() {
verifyCardTask = 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);
}
@Override
public void OnReadWait(int msec) {
WaitSecurityDelayDialog.OnReadWait(this, msec);
}
@Override
public void OnReadBeforeRequest(int timeout) {
WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout);
}
@Override
public void OnReadAfterRequest() {
WaitSecurityDelayDialog.onReadAfterRequest(this);
}
@Override
public void onResume() {
super.onResume();
mNfcManager.onResume();
}
@Override
public void onPause() {
super.onPause();
mNfcManager.onPause();
}
@Override
public void onStop() {
super.onStop();
mNfcManager.onStop();
}
}
package com.tangem.presentation.activity;
import android.app.Activity;
import android.content.Intent;
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.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.NfcManager;
import com.tangem.cardReader.Util;
import com.tangem.wallet.NoExtendedLengthSupportDialog;
import com.tangem.wallet.R;
import com.tangem.wallet.Tangem_Card;
import com.tangem.wallet.VerifyCardTask;
import com.tangem.wallet.WaitSecurityDelayDialog;
public class EmptyWalletActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback, CardProtocol.Notifications {
private static final int REQUEST_CODE_CREATE_NEW_WALLET_ACTIVITY = 2;
private static final int REQUEST_CODE_REQUEST_PIN2 = 3;
private static final int REQUEST_CODE_VERIFY_CARD = 4;
Tangem_Card mCard;
TextView tvCardID, tvIssuer, tvIssuerData, tvBlockchain;
ProgressBar progressBar;
ImageView ivBlockchain, ivPIN, ivPIN2orSecurityDelay, ivDeveloperVersion;
private NfcManager mNfcManager;
private final String logTag = "EmptyWalletActivity";
private boolean lastReadSuccess = true;
private VerifyCardTask verifyCardTask = null;
private int requestPIN2Count = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_empty_wallet);
MainActivity.commonInit(getApplicationContext());
mNfcManager = new NfcManager(this, this);
mCard = new Tangem_Card(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
tvCardID = findViewById(R.id.tvCardID);
tvCardID.setText(mCard.getCIDDescription());
tvIssuer = findViewById(R.id.tvIssuer);
tvIssuerData = findViewById(R.id.tvIssuerData);
tvBlockchain = findViewById(R.id.tvBlockchain);
tvIssuer.setText(mCard.getIssuerDescription());
tvIssuerData.setText(mCard.getIssuerDataDescription());
//tvBlockchain.setText(mCard.getBlockchain().getOfficialName());
tvBlockchain.setText(mCard.getBlockchainName());
progressBar = findViewById(R.id.progressBar);
ivBlockchain = findViewById(R.id.imgBlockchain);
ivPIN = findViewById(R.id.imgPIN);
ivPIN2orSecurityDelay = findViewById(R.id.imgPIN2orSecurityDelay);
ivDeveloperVersion = findViewById(R.id.imgDeveloperVersion);
ivBlockchain.setImageResource(mCard.getBlockchain().getImageResource(this, mCard.getTokenSymbol()));
if (mCard.useDefaultPIN1()) {
ivPIN.setImageResource(R.drawable.unlock_pin1);
ivPIN.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(EmptyWalletActivity.this, "This banknote is protected by default PIN1 code", Toast.LENGTH_LONG).show();
}
});
} else {
ivPIN.setImageResource(R.drawable.lock_pin1);
ivPIN.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(EmptyWalletActivity.this, "This banknote is protected by user's PIN1 code", Toast.LENGTH_LONG).show();
}
});
}
if (mCard.getPauseBeforePIN2() > 0 && (mCard.useDefaultPIN2() || !mCard.useSmartSecurityDelay())) {
ivPIN2orSecurityDelay.setImageResource(R.drawable.timer);
ivPIN2orSecurityDelay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(EmptyWalletActivity.this, String.format("This banknote will enforce %.0f seconds security delay for all operations requiring PIN2 code", mCard.getPauseBeforePIN2() / 1000.0), Toast.LENGTH_LONG).show();
}
});
} else if (mCard.useDefaultPIN2()) {
ivPIN2orSecurityDelay.setImageResource(R.drawable.unlock_pin2);
ivPIN2orSecurityDelay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(EmptyWalletActivity.this, "This banknote is protected by default PIN2 code", Toast.LENGTH_LONG).show();
}
});
} else {
ivPIN2orSecurityDelay.setImageResource(R.drawable.lock_pin2);
ivPIN2orSecurityDelay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(EmptyWalletActivity.this, "This banknote is protected by user's PIN2 code", Toast.LENGTH_LONG).show();
}
});
}
if (mCard.useDevelopersFirmware()) {
ivDeveloperVersion.setImageResource(R.drawable.ic_developer_version);
ivDeveloperVersion.setVisibility(View.VISIBLE);
ivDeveloperVersion.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(EmptyWalletActivity.this, "Unlocked banknote, only for development use", Toast.LENGTH_LONG).show();
}
});
} else {
ivDeveloperVersion.setVisibility(View.INVISIBLE);
}
Button btnNewWallet = findViewById(R.id.btnNewWallet);
btnNewWallet.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//CreateSelectBlockchainDialog();
requestPIN2Count = 0;
Intent intent = new Intent(getBaseContext(), RequestPINActivity.class);
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN2.toString());
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2);
}
});
if (getIntent().getExtras().containsKey(NfcAdapter.EXTRA_TAG)) {
Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tag != null) {
onTagDiscovered(tag);
}
}
}
private void doCreateNewWallet() {
Intent intent = new Intent(this, CreateNewWalletActivity.class);
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
// intent.putExtra("newPIN",mCard.getPIN());
// intent.putExtra("newPIN2","12345678");
startActivityForResult(intent, REQUEST_CODE_CREATE_NEW_WALLET_ACTIVITY);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_CREATE_NEW_WALLET_ACTIVITY) {
if (resultCode == Activity.RESULT_OK) {
if (data != null) {
data.putExtra("modification", "updateAndViewCard");
data.putExtra("updateDelay", 0);
setResult(Activity.RESULT_OK, data);
}
finish();
} else {
if (data != null && data.getExtras().containsKey("UID") && data.getExtras().containsKey("Card")) {
Tangem_Card updatedCard = new Tangem_Card(data.getStringExtra("UID"));
updatedCard.LoadFromBundle(data.getBundleExtra("Card"));
mCard = updatedCard;
}
if (resultCode == CreateNewWalletActivity.RESULT_INVALID_PIN && requestPIN2Count < 2) {
requestPIN2Count++;
Intent intent = new Intent(getBaseContext(), RequestPINActivity.class);
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN2.toString());
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
startActivityForResult(intent, REQUEST_CODE_REQUEST_PIN2);
return;
}
}
setResult(resultCode, data);
finish();
} else if (requestCode == REQUEST_CODE_REQUEST_PIN2) {
if (resultCode == Activity.RESULT_OK) {
doCreateNewWallet();
}
}
}
@Override
public void onTagDiscovered(Tag tag) {
try {
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 (!mCard.getUID().equals(sUID)) {
Log.d(logTag, "Invalid UID: " + sUID);
mNfcManager.IgnoreTag(isoDep.getTag());
return;
} else {
Log.v(logTag, "UID: " + sUID);
}
if (lastReadSuccess) {
isoDep.setTimeout(1000);
} else {
isoDep.setTimeout(65000);
}
//lastTag = tag;
verifyCardTask = new VerifyCardTask(this, mCard, mNfcManager, isoDep, this);
verifyCardTask.start();
} 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) {
verifyCardTask = 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));
Intent intent = new Intent(EmptyWalletActivity.this, VerifyCardActivity.class);
// TODO обновить карту mCard
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
startActivityForResult(intent, REQUEST_CODE_VERIFY_CARD);
//addCard(cardProtocol.getCard());
}
});
} else {
// remove last UIDs because of error and no card read
progressBar.post(new Runnable() {
@Override
public void run() {
lastReadSuccess = false;
if (cardProtocol.getError() instanceof CardProtocol.TangemException_ExtendedLengthNotSupported) {
if (!NoExtendedLengthSupportDialog.allreadyShowed) {
new NoExtendedLengthSupportDialog().show(getFragmentManager(), "NoExtendedLengthSupportDialog");
}
} else {
Toast.makeText(EmptyWalletActivity.this, "Try to scan again", Toast.LENGTH_LONG).show();
}
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
}
});
}
}
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() {
verifyCardTask = 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);
}
@Override
public void OnReadWait(int msec) {
WaitSecurityDelayDialog.OnReadWait(this, msec);
}
@Override
public void OnReadBeforeRequest(int timeout) {
WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout);
}
@Override
public void OnReadAfterRequest() {
WaitSecurityDelayDialog.onReadAfterRequest(this);
}
@Override
public void onResume() {
super.onResume();
mNfcManager.onResume();
}
@Override
public void onPause() {
super.onPause();
mNfcManager.onPause();
}
@Override
public void onStop() {
super.onStop();
mNfcManager.onStop();
}
}

View file

@ -1,37 +1,40 @@
package com.tangem.wallet;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
public class LoadedWalletActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loaded_wallet);
MainActivity.commonInit(getApplicationContext());
if( getIntent().getExtras().containsKey(NfcAdapter.EXTRA_TAG) )
{
Tag tag=getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tag != null ) {
LoadedWalletActivityFragment fragment=(LoadedWalletActivityFragment)(getSupportFragmentManager().findFragmentById(R.id.loaded_wallet_fragment));
fragment.onTagDiscovered(tag);
}
}
}
@Override
public void onBackPressed() {
LoadedWalletActivityFragment loadedWalletActivityFragment=(LoadedWalletActivityFragment) getSupportFragmentManager().findFragmentById(R.id.loaded_wallet_fragment);
Intent data= loadedWalletActivityFragment.prepareResultIntent();
data.putExtra("modification", "update");
setResult(Activity.RESULT_OK, data);
finish();
}
}
package com.tangem.presentation.activity;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.tangem.wallet.LoadedWalletActivityFragment;
import com.tangem.wallet.R;
public class LoadedWalletActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loaded_wallet);
MainActivity.commonInit(getApplicationContext());
if( getIntent().getExtras().containsKey(NfcAdapter.EXTRA_TAG) )
{
Tag tag=getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tag != null ) {
LoadedWalletActivityFragment fragment=(LoadedWalletActivityFragment)(getSupportFragmentManager().findFragmentById(R.id.loaded_wallet_fragment));
fragment.onTagDiscovered(tag);
}
}
}
@Override
public void onBackPressed() {
LoadedWalletActivityFragment loadedWalletActivityFragment=(LoadedWalletActivityFragment) getSupportFragmentManager().findFragmentById(R.id.loaded_wallet_fragment);
Intent data= loadedWalletActivityFragment.prepareResultIntent();
data.putExtra("modification", "update");
setResult(Activity.RESULT_OK, data);
finish();
}
}

View file

@ -1,68 +1,71 @@
package com.tangem.wallet;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
/**
* An example full-screen activity that shows and hides the system UI (i.e.
* status bar and navigation/system bar) with user interaction.
*/
public class LogoActivity extends AppCompatActivity {
private final Runnable mHideRunnable = new Runnable() {
@Override
public void run() {
hide();
}
};
ImageView imgLogo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_logo);
imgLogo= (ImageView) findViewById(R.id.imgLogo);
// Set up the user interaction to manually show or hide the system UI.
imgLogo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {hide();
}
});
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Trigger the initial hide() shortly after the activity has been
// created, to briefly hint to the user that UI controls
// are available.
TextView AppVersion = (TextView) findViewById(R.id.AppVersion);
AppVersion.setText("BETA v." + BuildConfig.VERSION_NAME);
if( !getIntent().getBooleanExtra("skipAutoHide",false)) {
delayedHide(1000);
}
}
private void hide() {
Intent intent=new Intent(getBaseContext(),MainActivity.class);
startActivity(intent);
finish();
}
/**
* Schedules a call to hide() in [delay] milliseconds, canceling any
* previously scheduled calls.
*/
private void delayedHide(int delayMillis) {
//imgLogo.removeCallbacks(mHideRunnable);
imgLogo.postDelayed(mHideRunnable, delayMillis);
}
}
package com.tangem.presentation.activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.tangem.wallet.BuildConfig;
import com.tangem.wallet.R;
/**
* An example full-screen activity that shows and hides the system UI (i.e.
* status bar and navigation/system bar) with user interaction.
*/
public class LogoActivity extends AppCompatActivity {
private final Runnable mHideRunnable = new Runnable() {
@Override
public void run() {
hide();
}
};
ImageView imgLogo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_logo);
imgLogo= (ImageView) findViewById(R.id.imgLogo);
// Set up the user interaction to manually show or hide the system UI.
imgLogo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {hide();
}
});
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Trigger the initial hide() shortly after the activity has been
// created, to briefly hint to the user that UI controls
// are available.
TextView AppVersion = (TextView) findViewById(R.id.AppVersion);
AppVersion.setText("BETA v." + BuildConfig.VERSION_NAME);
if( !getIntent().getBooleanExtra("skipAutoHide",false)) {
delayedHide(1000);
}
}
private void hide() {
Intent intent=new Intent(getBaseContext(),MainActivity.class);
startActivity(intent);
finish();
}
/**
* Schedules a call to hide() in [delay] milliseconds, canceling any
* previously scheduled calls.
*/
private void delayedHide(int delayMillis) {
//imgLogo.removeCallbacks(mHideRunnable);
imgLogo.postDelayed(mHideRunnable, delayMillis);
}
}

View file

@ -1,404 +1,413 @@
package com.tangem.wallet;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.PopupMenu;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Transformation;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.scottyab.rootbeer.RootBeer;
import com.skyfishjy.library.RippleBackground;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener {
public static final int DIALOG_ENABLE_INTERNET = 1;
private static final int REQUEST_CODE_SEND_EMAIL = 2;
private String logTag = "MainActivity";
public interface OnCardsClean {
void doClean();
}
// public interface OnCreateNFCDialog {
// Dialog CreateNFCDialog(int id, AlertDialogWrapper.Builder builder, LayoutInflater li);
// }
OnCardsClean onCardsClean;
// OnCreateNFCDialog onCreateNFCDialog;
NfcAdapter.ReaderCallback onNFCReaderCallback;
FloatingActionButton fab;
public void setOnCardsClean(OnCardsClean onCardsClean) {
this.onCardsClean = onCardsClean;
}
// public void setOnCreateNFCDialog(OnCreateNFCDialog onCreateNFCDialog) {
// this.onCreateNFCDialog = onCreateNFCDialog;
// }
public void setNfcAdapterReaderCallback(NfcAdapter.ReaderCallback callback) {
this.onNFCReaderCallback = callback;
}
public void showCleanButton() {
findViewById(R.id.tvTapPrompt).setVisibility(View.INVISIBLE);
}
public void hideCleanButton() {
findViewById(R.id.tvTapPrompt).setVisibility(View.VISIBLE);
}
public static class RootFoundDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.tangem_logo_small_new)
.setTitle("Your Android device is rooted. Security at risk!")
.setCancelable(false)
.setPositiveButton("Got it",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
}
)
.create();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RootBeer rootBeer = new RootBeer(this);
if (rootBeer.isRootedWithoutBusyBoxCheck()) {
//we found indication of root
new RootFoundDialog().show(getFragmentManager(), "RootFoundDialog");
}
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
commonInit(getApplicationContext());
TextView tvNFCHint = findViewById(R.id.tvNFCHint);
if(tvNFCHint != null)
{
// tvNFCHint.setText("Scan a banknote with your\n" + PhoneUtility.GetPhoneName() + "\nas shown above");
tvNFCHint.setText("Scan a banknote with your\n smartphone as shown above");
}
DeviceNFCAntennaLocation antenna = new DeviceNFCAntennaLocation();
antenna.getAntennaLocation();
final LinearLayout hand = findViewById(R.id.llHand);
final LinearLayout nfc = findViewById(R.id.llNFC);
final RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) hand.getLayoutParams();
final RelativeLayout.LayoutParams lp2 = (RelativeLayout.LayoutParams) nfc.getLayoutParams();
final float dp = getResources().getDisplayMetrics().density;
final float lm = dp*(69 + antenna.X * 75);
lp.topMargin = (int) (dp*(-100 + antenna.Y * 250));
lp2.topMargin = (int) (dp*(-125 + antenna.Y * 250));
nfc.setLayoutParams(lp2);
Animation a = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
lp.leftMargin = (int)(lm * interpolatedTime);
hand.setLayoutParams(lp);
}
};
a.setDuration(2000); // in ms
a.setInterpolator(new DecelerateInterpolator());
hand.startAnimation(a);
fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showMenu(view);
}
});
MainActivityFragment mainActivityFragment=(MainActivityFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentMain);
if( mainActivityFragment.getCardListAdapter().getItemCount()>0 )
{
showCleanButton();
}else {
hideCleanButton();
}
final RippleBackground rippleBackground=(RippleBackground)findViewById(R.id.imNFC);
rippleBackground.startRippleAnimation();
Intent intent = getIntent();
if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tag != null && onNFCReaderCallback != null) {
onNFCReaderCallback.onTagDiscovered(tag);
}
}
}
public static void commonInit(Context context)
{
if( PINStorage.needInit() ) {
PINStorage.Init(context);
}
if( LastSignStorage.needInit() ) {
LastSignStorage.Init(context);
}
}
@Override
protected void onDestroy() {
// Logger.StopSaveToFile(getApplicationContext());
super.onDestroy();
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tag != null && onNFCReaderCallback != null) {
onNFCReaderCallback.onTagDiscovered(tag);
}
}
}
@Override
public boolean onKeyDown(int keycode, KeyEvent e) {
switch (keycode) {
case KeyEvent.KEYCODE_MENU:
fab.requestFocus();
showMenu(fab);
return true;
}
return super.onKeyDown(keycode, e);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
if( BuildConfig.DEBUG ) {
for(int i=0; i<menu.size(); i++ ) menu.getItem(i).setVisible(true);
}
return true;
}
public class Compress {
private static final int BUFFER = 2048;
private String[] _files;
private String _zipFile;
Compress(String[] files, String zipFile) {
_files = files;
_zipFile = zipFile;
}
void zip() {
try {
BufferedInputStream origin = null;
FileOutputStream dest = new FileOutputStream(_zipFile);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
byte data[] = new byte[BUFFER];
for (String _file : _files) {
Log.v("Compress", "Adding: " + _file);
FileInputStream fi = new FileInputStream(_file);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(_file.substring(_file.lastIndexOf("/") + 1));
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
File zipFile = null;
private void sendEmail(String subject, String text, File[] filelocations) {
if (zipFile != null) return;
try {
Intent intent = new Intent(Intent.ACTION_SEND)
//.setData(new Uri.Builder().scheme("mailto").build())
.setType("text/plain")
.putExtra(Intent.EXTRA_EMAIL, new String[]{"android@tangem.com"})
.putExtra(Intent.EXTRA_SUBJECT, subject)
.putExtra(Intent.EXTRA_TEXT, text);
if (filelocations != null && filelocations.length > 0) {
String[] fileNames = new String[filelocations.length];
for (int i = 0; i < filelocations.length; i++)
fileNames[i] = filelocations[i].getAbsolutePath();
zipFile = File.createTempFile("tangemLogs", ".zip", filelocations[0].getParentFile());
Compress compress = new Compress(fileNames, zipFile.getAbsolutePath());
compress.zip();
Log.e(logTag, String.format("Send %d bytes zip with logs", zipFile.length()));
Uri attachment = Uri.parse("content://" + LogFileProvider.AUTHORITY + "/"
+ zipFile.getName());
intent.putExtra(Intent.EXTRA_STREAM, attachment);
zipFile.deleteOnExit();
}
List<ResolveInfo> activities = getPackageManager().queryIntentActivities(intent, 0);
boolean isIntentSafe = activities.size() > 0;
if (isIntentSafe) {
startActivity(intent);
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_SEND_EMAIL) {
if (zipFile != null) {
zipFile.delete();
zipFile = null;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
public void showMenu(View v) {
PopupMenu popup = new PopupMenu(this, v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.menu_main, popup.getMenu());
if( BuildConfig.DEBUG ) {
for(int i=0; i<popup.getMenu().size(); i++ ) popup.getMenu().getItem(i).setVisible(true);
}
popup.setOnMenuItemClickListener(this);
popup.show();
}
@Override
public boolean onMenuItemClick(MenuItem item) {
return onOptionsItemSelected(item);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
switch (id) {
case R.id.sendLogs:
File f = null;
try {
f = Logger.collectLogs(this);
if (f != null) {
Log.e(logTag, String.format("Collect %d log bytes", f.length()));
sendEmail("Logs", PhoneUtility.getDeviceInfo(), new File[]{f});
} else {
Log.e(logTag, "Can't create temporaly log file");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (f != null && f.exists()) {
f.delete();
}
}
return true;
case R.id.managePIN:
showSavePinActivity();
return true;
case R.id.managePIN2:
showSavePin2Activity();
return true;
case R.id.cleanCards:
if (onCardsClean != null) onCardsClean.doClean();
hideCleanButton();
return true;
case R.id.about:
showLogoActivity();
return true;
}
return super.onOptionsItemSelected(item);
}
private void showLogoActivity() {
Intent intent = new Intent(getBaseContext(), LogoActivity.class);
intent.putExtra("skipAutoHide",true);
startActivity(intent);
}
private void showSavePinActivity() {
Intent intent = new Intent(getBaseContext(), SavePINActivity.class);
intent.putExtra("PIN2", false);
startActivity(intent);
}
private void showSavePin2Activity() {
Intent intent = new Intent(getBaseContext(), SavePINActivity.class);
intent.putExtra("PIN2", true);
startActivity(intent);
}
}
package com.tangem.presentation.activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.PopupMenu;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Transformation;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.scottyab.rootbeer.RootBeer;
import com.skyfishjy.library.RippleBackground;
import com.tangem.wallet.BuildConfig;
import com.tangem.wallet.DeviceNFCAntennaLocation;
import com.tangem.wallet.LastSignStorage;
import com.tangem.wallet.LogFileProvider;
import com.tangem.wallet.Logger;
import com.tangem.wallet.MainActivityFragment;
import com.tangem.wallet.PINStorage;
import com.tangem.wallet.PhoneUtility;
import com.tangem.wallet.R;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener {
public static final int DIALOG_ENABLE_INTERNET = 1;
private static final int REQUEST_CODE_SEND_EMAIL = 2;
private String logTag = "MainActivity";
public interface OnCardsClean {
void doClean();
}
// public interface OnCreateNFCDialog {
// Dialog CreateNFCDialog(int id, AlertDialogWrapper.Builder builder, LayoutInflater li);
// }
OnCardsClean onCardsClean;
// OnCreateNFCDialog onCreateNFCDialog;
NfcAdapter.ReaderCallback onNFCReaderCallback;
FloatingActionButton fab;
public void setOnCardsClean(OnCardsClean onCardsClean) {
this.onCardsClean = onCardsClean;
}
// public void setOnCreateNFCDialog(OnCreateNFCDialog onCreateNFCDialog) {
// this.onCreateNFCDialog = onCreateNFCDialog;
// }
public void setNfcAdapterReaderCallback(NfcAdapter.ReaderCallback callback) {
this.onNFCReaderCallback = callback;
}
public void showCleanButton() {
findViewById(R.id.tvTapPrompt).setVisibility(View.INVISIBLE);
}
public void hideCleanButton() {
findViewById(R.id.tvTapPrompt).setVisibility(View.VISIBLE);
}
public static class RootFoundDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.tangem_logo_small_new)
.setTitle("Your Android device is rooted. Security at risk!")
.setCancelable(false)
.setPositiveButton("Got it",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
}
)
.create();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RootBeer rootBeer = new RootBeer(this);
if (rootBeer.isRootedWithoutBusyBoxCheck()) {
//we found indication of root
new RootFoundDialog().show(getFragmentManager(), "RootFoundDialog");
}
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
commonInit(getApplicationContext());
TextView tvNFCHint = findViewById(R.id.tvNFCHint);
if(tvNFCHint != null)
{
// tvNFCHint.setText("Scan a banknote with your\n" + PhoneUtility.GetPhoneName() + "\nas shown above");
tvNFCHint.setText("Scan a banknote with your\n smartphone as shown above");
}
DeviceNFCAntennaLocation antenna = new DeviceNFCAntennaLocation();
antenna.getAntennaLocation();
final LinearLayout hand = findViewById(R.id.llHand);
final LinearLayout nfc = findViewById(R.id.llNFC);
final RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) hand.getLayoutParams();
final RelativeLayout.LayoutParams lp2 = (RelativeLayout.LayoutParams) nfc.getLayoutParams();
final float dp = getResources().getDisplayMetrics().density;
final float lm = dp*(69 + antenna.X * 75);
lp.topMargin = (int) (dp*(-100 + antenna.Y * 250));
lp2.topMargin = (int) (dp*(-125 + antenna.Y * 250));
nfc.setLayoutParams(lp2);
Animation a = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
lp.leftMargin = (int)(lm * interpolatedTime);
hand.setLayoutParams(lp);
}
};
a.setDuration(2000); // in ms
a.setInterpolator(new DecelerateInterpolator());
hand.startAnimation(a);
fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showMenu(view);
}
});
MainActivityFragment mainActivityFragment=(MainActivityFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentMain);
if( mainActivityFragment.getCardListAdapter().getItemCount()>0 )
{
showCleanButton();
}else {
hideCleanButton();
}
final RippleBackground rippleBackground=(RippleBackground)findViewById(R.id.imNFC);
rippleBackground.startRippleAnimation();
Intent intent = getIntent();
if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tag != null && onNFCReaderCallback != null) {
onNFCReaderCallback.onTagDiscovered(tag);
}
}
}
public static void commonInit(Context context)
{
if( PINStorage.needInit() ) {
PINStorage.Init(context);
}
if( LastSignStorage.needInit() ) {
LastSignStorage.Init(context);
}
}
@Override
protected void onDestroy() {
// Logger.StopSaveToFile(getApplicationContext());
super.onDestroy();
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tag != null && onNFCReaderCallback != null) {
onNFCReaderCallback.onTagDiscovered(tag);
}
}
}
@Override
public boolean onKeyDown(int keycode, KeyEvent e) {
switch (keycode) {
case KeyEvent.KEYCODE_MENU:
fab.requestFocus();
showMenu(fab);
return true;
}
return super.onKeyDown(keycode, e);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
if( BuildConfig.DEBUG ) {
for(int i=0; i<menu.size(); i++ ) menu.getItem(i).setVisible(true);
}
return true;
}
public class Compress {
private static final int BUFFER = 2048;
private String[] _files;
private String _zipFile;
Compress(String[] files, String zipFile) {
_files = files;
_zipFile = zipFile;
}
void zip() {
try {
BufferedInputStream origin = null;
FileOutputStream dest = new FileOutputStream(_zipFile);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
byte data[] = new byte[BUFFER];
for (String _file : _files) {
Log.v("Compress", "Adding: " + _file);
FileInputStream fi = new FileInputStream(_file);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(_file.substring(_file.lastIndexOf("/") + 1));
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
File zipFile = null;
private void sendEmail(String subject, String text, File[] filelocations) {
if (zipFile != null) return;
try {
Intent intent = new Intent(Intent.ACTION_SEND)
//.setData(new Uri.Builder().scheme("mailto").build())
.setType("text/plain")
.putExtra(Intent.EXTRA_EMAIL, new String[]{"android@tangem.com"})
.putExtra(Intent.EXTRA_SUBJECT, subject)
.putExtra(Intent.EXTRA_TEXT, text);
if (filelocations != null && filelocations.length > 0) {
String[] fileNames = new String[filelocations.length];
for (int i = 0; i < filelocations.length; i++)
fileNames[i] = filelocations[i].getAbsolutePath();
zipFile = File.createTempFile("tangemLogs", ".zip", filelocations[0].getParentFile());
Compress compress = new Compress(fileNames, zipFile.getAbsolutePath());
compress.zip();
Log.e(logTag, String.format("Send %d bytes zip with logs", zipFile.length()));
Uri attachment = Uri.parse("content://" + LogFileProvider.AUTHORITY + "/"
+ zipFile.getName());
intent.putExtra(Intent.EXTRA_STREAM, attachment);
zipFile.deleteOnExit();
}
List<ResolveInfo> activities = getPackageManager().queryIntentActivities(intent, 0);
boolean isIntentSafe = activities.size() > 0;
if (isIntentSafe) {
startActivity(intent);
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_SEND_EMAIL) {
if (zipFile != null) {
zipFile.delete();
zipFile = null;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
public void showMenu(View v) {
PopupMenu popup = new PopupMenu(this, v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.menu_main, popup.getMenu());
if( BuildConfig.DEBUG ) {
for(int i=0; i<popup.getMenu().size(); i++ ) popup.getMenu().getItem(i).setVisible(true);
}
popup.setOnMenuItemClickListener(this);
popup.show();
}
@Override
public boolean onMenuItemClick(MenuItem item) {
return onOptionsItemSelected(item);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
switch (id) {
case R.id.sendLogs:
File f = null;
try {
f = Logger.collectLogs(this);
if (f != null) {
Log.e(logTag, String.format("Collect %d log bytes", f.length()));
sendEmail("Logs", PhoneUtility.getDeviceInfo(), new File[]{f});
} else {
Log.e(logTag, "Can't create temporaly log file");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (f != null && f.exists()) {
f.delete();
}
}
return true;
case R.id.managePIN:
showSavePinActivity();
return true;
case R.id.managePIN2:
showSavePin2Activity();
return true;
case R.id.cleanCards:
if (onCardsClean != null) onCardsClean.doClean();
hideCleanButton();
return true;
case R.id.about:
showLogoActivity();
return true;
}
return super.onOptionsItemSelected(item);
}
private void showLogoActivity() {
Intent intent = new Intent(getBaseContext(), LogoActivity.class);
intent.putExtra("skipAutoHide",true);
startActivity(intent);
}
private void showSavePinActivity() {
Intent intent = new Intent(getBaseContext(), SavePINActivity.class);
intent.putExtra("PIN2", false);
startActivity(intent);
}
private void showSavePin2Activity() {
Intent intent = new Intent(getBaseContext(), SavePINActivity.class);
intent.putExtra("PIN2", true);
startActivity(intent);
}
}

View file

@ -1,237 +1,227 @@
package com.tangem.wallet;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.Html;
import android.text.Spanned;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import com.tangem.cardReader.NfcManager;
import java.io.IOException;
public class PreparePaymentActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback {
private static final int REQUEST_CODE_SCAN_QR = 1;
private static final int REQUEST_CODE_SEND_PAYMENT = 2;
Button btnVerify;
EditText etWallet;
EditText etAmount;
TextView tvCurrency;
TextView tvCardId, tvBalance, tvBalanceEquivalent, tvAmountEquivalent;
ImageView ivCamera;
boolean use_mCurrency;
Tangem_Card mCard;
private NfcManager mNfcManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_prepare_payment);
MainActivity.commonInit(getApplicationContext());
mNfcManager = new NfcManager(this, this);
mCard = new Tangem_Card(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
btnVerify = (Button) findViewById(R.id.btnVerify);
etWallet = (EditText) findViewById(R.id.etWallet);
etAmount = (EditText) findViewById(R.id.etAmount);
ivCamera = (ImageView) findViewById(R.id.ivCamera);
tvCurrency = (TextView) findViewById(R.id.tvCurrency);
tvCardId = (TextView) findViewById(R.id.tvCardID);
tvBalance = (TextView) findViewById(R.id.tvBalance);
tvBalanceEquivalent = (TextView) findViewById(R.id.tvBalanceEquivalent);
tvAmountEquivalent = (TextView) findViewById(R.id.tvAmountEquivalent);
tvCardId.setText(mCard.getCIDDescription());
CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
if (mCard.getBlockchain() == Blockchain.Token) {
Spanned html = Html.fromHtml(engine.GetBalanceWithAlter(mCard));
tvBalance.setText(html);
} else {
tvBalance.setText(engine.GetBalanceWithAlter(mCard));
}
tvBalanceEquivalent.setText(engine.GetBalanceEquivalent(mCard));
if(etAmount != null && mCard.getRemainingSignatures()<2)
{
etAmount.setEnabled(false);
}
if( !mCard.getAmountEquivalentDescriptionAvailable())
{
tvBalanceEquivalent.setError("Service unavailable");
}else{
tvBalanceEquivalent.setError(null);
}
etAmount.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
try {
CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
tvAmountEquivalent.setText(engine.GetAmountEqualentDescriptor(mCard, etAmount.getText().toString()));
if (!mCard.getAmountEquivalentDescriptionAvailable()) {
tvAmountEquivalent.setError("Service unavailable");
}else{
tvAmountEquivalent.setError(null);
}
} catch (Exception e) {
e.printStackTrace();
tvAmountEquivalent.setText("");
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
if(mCard.getBlockchain() == Blockchain.Ethereum || mCard.getBlockchain() == Blockchain.EthereumTestNet)
{
tvCurrency.setText(engine.GetBalanceCurrency(mCard));
use_mCurrency=false;
etAmount.setText(engine.GetBalanceValue(mCard));
}
else if(mCard.getBlockchain() == Blockchain.Bitcoin || mCard.getBlockchain() == Blockchain.BitcoinTestNet)
{
Double balance = engine.GetBalanceLong(mCard) / (mCard.getBlockchain().getMultiplier() / 1000.0);
tvCurrency.setText("m" + mCard.getBlockchain().getCurrency());
use_mCurrency=true;
String output = FormatUtil.DoubleToString(balance);
etAmount.setText(output);
}
else if(mCard.getBlockchain() == Blockchain.BitcoinCash || mCard.getBlockchain() == Blockchain.BitcoinCashTestNet)
{
Double balance = engine.GetBalanceLong(mCard) / (mCard.getBlockchain().getMultiplier() / 1000.0);
tvCurrency.setText("m" + mCard.getBlockchain().getCurrency());
use_mCurrency=true;
String output = FormatUtil.DoubleToString(balance);
etAmount.setText(output);
}
else
{
tvCurrency.setText(engine.GetBalanceCurrency(mCard));
use_mCurrency=false;
etAmount.setText(engine.GetBalanceValue(mCard));
}
btnVerify.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String strAmount;
strAmount=etAmount.getText().toString();
CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
try {
if(!engine.CheckAmount(mCard, etAmount.getText().toString()))
{
etAmount.setError("Not enough funds on your card");
}
}
catch(Exception e)
{
etAmount.setError("Unknown amount format");
return;
}
boolean checkAddress = engine.ValdateAddress(etWallet.getText().toString(), mCard);
if(!checkAddress)
{
etWallet.setError("Incorrect destination wallet address");
return;
}
if(etWallet.getText().toString().equals(mCard.getWallet()))
{
etWallet.setError("Destination wallet address equal source address");
return;
}
Intent intent = new Intent(getBaseContext(), ConfirmPaymentActivity.class);
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
intent.putExtra("Wallet", etWallet.getText().toString());
intent.putExtra("Amount", strAmount);
startActivityForResult(intent, REQUEST_CODE_SEND_PAYMENT);
}
});
ivCamera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getBaseContext(), QRScanActivity.class);
startActivityForResult(intent, REQUEST_CODE_SCAN_QR);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_SCAN_QR && resultCode == Activity.RESULT_OK && data != null && data.getExtras().containsKey("QRCode")) {
String code = data.getStringExtra("QRCode");
if(code.contains("bitcoin:"))
{
String tmp[] = code.split("bitcoin:");
code = tmp[1];
}
etWallet.setText(code);
}else if (requestCode == REQUEST_CODE_SEND_PAYMENT ) {
setResult(resultCode,data);
finish();
}
}
@Override
public void onTagDiscovered(Tag tag) {
try {
Log.w(getClass().getName(),"Ignore discovered tag!");
mNfcManager.IgnoreTag(tag);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onResume() {
super.onResume();
mNfcManager.onResume();
}
@Override
public void onPause() {
super.onPause();
mNfcManager.onPause();
}
@Override
public void onStop() {
super.onStop();
mNfcManager.onStop();
}
package com.tangem.presentation.activity;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.Html;
import android.text.Spanned;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import com.tangem.cardReader.NfcManager;
import com.tangem.wallet.Blockchain;
import com.tangem.wallet.CoinEngine;
import com.tangem.wallet.CoinEngineFactory;
import com.tangem.wallet.FormatUtil;
import com.tangem.wallet.R;
import com.tangem.wallet.Tangem_Card;
import java.io.IOException;
public class PreparePaymentActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback {
private static final int REQUEST_CODE_SCAN_QR = 1;
private static final int REQUEST_CODE_SEND_PAYMENT = 2;
Button btnVerify;
EditText etWallet;
EditText etAmount;
TextView tvCurrency;
TextView tvCardId, tvBalance, tvBalanceEquivalent, tvAmountEquivalent;
ImageView ivCamera;
boolean use_mCurrency;
Tangem_Card mCard;
private NfcManager mNfcManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_prepare_payment);
MainActivity.commonInit(getApplicationContext());
mNfcManager = new NfcManager(this, this);
mCard = new Tangem_Card(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
btnVerify = (Button) findViewById(R.id.btnVerify);
etWallet = (EditText) findViewById(R.id.etWallet);
etAmount = (EditText) findViewById(R.id.etAmount);
ivCamera = (ImageView) findViewById(R.id.ivCamera);
tvCurrency = (TextView) findViewById(R.id.tvCurrency);
tvCardId = (TextView) findViewById(R.id.tvCardID);
tvBalance = (TextView) findViewById(R.id.tvBalance);
tvBalanceEquivalent = (TextView) findViewById(R.id.tvBalanceEquivalent);
tvAmountEquivalent = (TextView) findViewById(R.id.tvAmountEquivalent);
tvCardId.setText(mCard.getCIDDescription());
CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
if (mCard.getBlockchain() == Blockchain.Token) {
Spanned html = Html.fromHtml(engine.GetBalanceWithAlter(mCard));
tvBalance.setText(html);
} else {
tvBalance.setText(engine.GetBalanceWithAlter(mCard));
}
tvBalanceEquivalent.setText(engine.GetBalanceEquivalent(mCard));
if (etAmount != null && mCard.getRemainingSignatures() < 2) {
etAmount.setEnabled(false);
}
if (!mCard.getAmountEquivalentDescriptionAvailable()) {
tvBalanceEquivalent.setError("Service unavailable");
} else {
tvBalanceEquivalent.setError(null);
}
etAmount.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
try {
CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
tvAmountEquivalent.setText(engine.GetAmountEqualentDescriptor(mCard, etAmount.getText().toString()));
if (!mCard.getAmountEquivalentDescriptionAvailable()) {
tvAmountEquivalent.setError("Service unavailable");
} else {
tvAmountEquivalent.setError(null);
}
} catch (Exception e) {
e.printStackTrace();
tvAmountEquivalent.setText("");
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
if (mCard.getBlockchain() == Blockchain.Ethereum || mCard.getBlockchain() == Blockchain.EthereumTestNet) {
tvCurrency.setText(engine.GetBalanceCurrency(mCard));
use_mCurrency = false;
etAmount.setText(engine.GetBalanceValue(mCard));
} else if (mCard.getBlockchain() == Blockchain.Bitcoin || mCard.getBlockchain() == Blockchain.BitcoinTestNet) {
Double balance = engine.GetBalanceLong(mCard) / (mCard.getBlockchain().getMultiplier() / 1000.0);
tvCurrency.setText("m" + mCard.getBlockchain().getCurrency());
use_mCurrency = true;
String output = FormatUtil.DoubleToString(balance);
etAmount.setText(output);
} else if (mCard.getBlockchain() == Blockchain.BitcoinCash || mCard.getBlockchain() == Blockchain.BitcoinCashTestNet) {
Double balance = engine.GetBalanceLong(mCard) / (mCard.getBlockchain().getMultiplier() / 1000.0);
tvCurrency.setText("m" + mCard.getBlockchain().getCurrency());
use_mCurrency = true;
String output = FormatUtil.DoubleToString(balance);
etAmount.setText(output);
} else {
tvCurrency.setText(engine.GetBalanceCurrency(mCard));
use_mCurrency = false;
etAmount.setText(engine.GetBalanceValue(mCard));
}
btnVerify.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String strAmount;
strAmount = etAmount.getText().toString();
CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
try {
if (!engine.CheckAmount(mCard, etAmount.getText().toString())) {
etAmount.setError("Not enough funds on your card");
}
} catch (Exception e) {
etAmount.setError("Unknown amount format");
return;
}
boolean checkAddress = engine.ValdateAddress(etWallet.getText().toString(), mCard);
if (!checkAddress) {
etWallet.setError("Incorrect destination wallet address");
return;
}
if (etWallet.getText().toString().equals(mCard.getWallet())) {
etWallet.setError("Destination wallet address equal source address");
return;
}
Intent intent = new Intent(getBaseContext(), ConfirmPaymentActivity.class);
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
intent.putExtra("Wallet", etWallet.getText().toString());
intent.putExtra("Amount", strAmount);
startActivityForResult(intent, REQUEST_CODE_SEND_PAYMENT);
}
});
ivCamera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getBaseContext(), QRScanActivity.class);
startActivityForResult(intent, REQUEST_CODE_SCAN_QR);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_SCAN_QR && resultCode == Activity.RESULT_OK && data != null && data.getExtras().containsKey("QRCode")) {
String code = data.getStringExtra("QRCode");
if (code.contains("bitcoin:")) {
String tmp[] = code.split("bitcoin:");
code = tmp[1];
}
etWallet.setText(code);
} else if (requestCode == REQUEST_CODE_SEND_PAYMENT) {
setResult(resultCode, data);
finish();
}
}
@Override
public void onTagDiscovered(Tag tag) {
try {
Log.w(getClass().getName(), "Ignore discovered tag!");
mNfcManager.IgnoreTag(tag);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onResume() {
super.onResume();
mNfcManager.onResume();
}
@Override
public void onPause() {
super.onPause();
mNfcManager.onPause();
}
@Override
public void onStop() {
super.onStop();
mNfcManager.onStop();
}
}

View file

@ -1,333 +1,338 @@
package com.tangem.wallet;
import android.app.Activity;
import android.content.Intent;
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.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.NfcManager;
import com.tangem.cardReader.Util;
public class PurgeActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback, CardProtocol.Notifications {
public static final int RESULT_INVALID_PIN = Activity.RESULT_FIRST_USER;
private Tangem_Card mCard;
private TextView tvCardID;
private NfcManager mNfcManager;
private static final String logTag = "Purge";
private ProgressBar progressBar;
private PurgeTask purgeTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_purge);
MainActivity.commonInit(getApplicationContext());
mCard = new Tangem_Card(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
tvCardID = (TextView) findViewById(R.id.tvCardID);
tvCardID.setText(mCard.getCIDDescription());
mNfcManager = new NfcManager(this, this);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
progressBar.setVisibility(View.INVISIBLE);
}
@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);
Log.v(logTag, "UID: " + sUID);
if (sUID.equals(mCard.getUID())) {
isoDep.setTimeout(mCard.getPauseBeforePIN2() + 65000);
purgeTask = new PurgeTask(isoDep, this);
purgeTask.start();
} else {
Log.d(logTag, "Mismatch card UID (" + sUID + " instead of " + mCard.getUID() + ")");
mNfcManager.IgnoreTag(isoDep.getTag());
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onResume() {
super.onResume();
mNfcManager.onResume();
}
@Override
public void onPause() {
mNfcManager.onPause();
if (purgeTask != null) {
purgeTask.cancel(true);
}
super.onPause();
}
@Override
public void onStop() {
// dismiss enable NFC dialog
mNfcManager.onStop();
if (purgeTask != null) {
purgeTask.cancel(true);
}
super.onStop();
}
// @Override
// public Dialog CreateNFCDialog(int id, AlertDialogWrapper.Builder builder, LayoutInflater li) {
// return mNfcManager.onCreateDialog(id, builder, li);
// }
private class PurgeTask extends Thread {
private String txOutAddress;
IsoDep mIsoDep;
CardProtocol.Notifications mNotifications;
private boolean isCancelled = false;
public PurgeTask(IsoDep isoDep, CardProtocol.Notifications notifications) {
mIsoDep = isoDep;
mNotifications = notifications;
}
@Override
public void run() {
if (mIsoDep == null) {
return;
}
CardProtocol protocol = new CardProtocol(getBaseContext(), mIsoDep, mCard, mNotifications);
mNotifications.OnReadStart(protocol);
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 {
mNotifications.OnReadProgress(protocol, 5);
Log.i("PurgeTask", "[-- Start purge --]");
if (isCancelled) return;
if (mCard.getPauseBeforePIN2() > 0) {
mNotifications.OnReadWait(mCard.getPauseBeforePIN2());
}
// try {
protocol.run_PurgeWallet(PINStorage.getPIN2());
// } finally {
// mNotifications.OnReadWait(0);
// }
mNotifications.OnReadProgress(protocol, 50);
protocol.run_Read();
mNotifications.OnReadProgress(protocol, 100);
if (isCancelled) return;
} finally {
mNfcManager.IgnoreTag(mIsoDep.getTag());
}
} catch (Exception e) {
e.printStackTrace();
protocol.setError(e);
} finally {
Log.i("PurgeTask", "[-- Finish purge --]");
mNotifications.OnReadFinish(protocol);
}
}
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();
}
}
}
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) {
purgeTask = 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));
Intent intent = new Intent();
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
setResult(Activity.RESULT_OK, intent);
finish();
}
});
} else {
if (cardProtocol.getError() instanceof CardProtocol.TangemException_InvalidPIN) {
progressBar.post(new Runnable() {
@Override
public void run() {
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
}
});
progressBar.postDelayed(new Runnable() {
@Override
public void run() {
try {
progressBar.setProgress(0);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
progressBar.setVisibility(View.INVISIBLE);
Intent intent = new Intent();
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
intent.putExtra("message", "Cannot erase wallet. Make sure you enter correct PIN2!");
setResult(RESULT_INVALID_PIN, intent);
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}, 500);
return;
} else {
progressBar.post(new Runnable() {
@Override
public void run() {
if (cardProtocol.getError() instanceof CardProtocol.TangemException_ExtendedLengthNotSupported) {
if (!NoExtendedLengthSupportDialog.allreadyShowed) {
new NoExtendedLengthSupportDialog().show(getFragmentManager(), "NoExtendedLengthSupportDialog");
}
} else {
Toast.makeText(getBaseContext(), "Try to scan again", Toast.LENGTH_LONG).show();
}
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
}
});
}
}
}
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() {
purgeTask = 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);
}
@Override
public void OnReadWait(final int msec) {
WaitSecurityDelayDialog.OnReadWait(this, msec);
}
@Override
public void OnReadBeforeRequest(int timeout) {
WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout);
}
@Override
public void OnReadAfterRequest() {
WaitSecurityDelayDialog.onReadAfterRequest(this);
}
}
package com.tangem.presentation.activity;
import android.app.Activity;
import android.content.Intent;
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.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.NfcManager;
import com.tangem.cardReader.Util;
import com.tangem.wallet.NoExtendedLengthSupportDialog;
import com.tangem.wallet.PINStorage;
import com.tangem.wallet.R;
import com.tangem.wallet.Tangem_Card;
import com.tangem.wallet.WaitSecurityDelayDialog;
public class PurgeActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback, CardProtocol.Notifications {
public static final int RESULT_INVALID_PIN = Activity.RESULT_FIRST_USER;
private Tangem_Card mCard;
private TextView tvCardID;
private NfcManager mNfcManager;
private static final String logTag = "Purge";
private ProgressBar progressBar;
private PurgeTask purgeTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_purge);
MainActivity.commonInit(getApplicationContext());
mCard = new Tangem_Card(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
tvCardID = (TextView) findViewById(R.id.tvCardID);
tvCardID.setText(mCard.getCIDDescription());
mNfcManager = new NfcManager(this, this);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
progressBar.setVisibility(View.INVISIBLE);
}
@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);
Log.v(logTag, "UID: " + sUID);
if (sUID.equals(mCard.getUID())) {
isoDep.setTimeout(mCard.getPauseBeforePIN2() + 65000);
purgeTask = new PurgeTask(isoDep, this);
purgeTask.start();
} else {
Log.d(logTag, "Mismatch card UID (" + sUID + " instead of " + mCard.getUID() + ")");
mNfcManager.IgnoreTag(isoDep.getTag());
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onResume() {
super.onResume();
mNfcManager.onResume();
}
@Override
public void onPause() {
mNfcManager.onPause();
if (purgeTask != null) {
purgeTask.cancel(true);
}
super.onPause();
}
@Override
public void onStop() {
// dismiss enable NFC dialog
mNfcManager.onStop();
if (purgeTask != null) {
purgeTask.cancel(true);
}
super.onStop();
}
// @Override
// public Dialog CreateNFCDialog(int id, AlertDialogWrapper.Builder builder, LayoutInflater li) {
// return mNfcManager.onCreateDialog(id, builder, li);
// }
private class PurgeTask extends Thread {
private String txOutAddress;
IsoDep mIsoDep;
CardProtocol.Notifications mNotifications;
private boolean isCancelled = false;
public PurgeTask(IsoDep isoDep, CardProtocol.Notifications notifications) {
mIsoDep = isoDep;
mNotifications = notifications;
}
@Override
public void run() {
if (mIsoDep == null) {
return;
}
CardProtocol protocol = new CardProtocol(getBaseContext(), mIsoDep, mCard, mNotifications);
mNotifications.OnReadStart(protocol);
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 {
mNotifications.OnReadProgress(protocol, 5);
Log.i("PurgeTask", "[-- Start purge --]");
if (isCancelled) return;
if (mCard.getPauseBeforePIN2() > 0) {
mNotifications.OnReadWait(mCard.getPauseBeforePIN2());
}
// try {
protocol.run_PurgeWallet(PINStorage.getPIN2());
// } finally {
// mNotifications.OnReadWait(0);
// }
mNotifications.OnReadProgress(protocol, 50);
protocol.run_Read();
mNotifications.OnReadProgress(protocol, 100);
if (isCancelled) return;
} finally {
mNfcManager.IgnoreTag(mIsoDep.getTag());
}
} catch (Exception e) {
e.printStackTrace();
protocol.setError(e);
} finally {
Log.i("PurgeTask", "[-- Finish purge --]");
mNotifications.OnReadFinish(protocol);
}
}
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();
}
}
}
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) {
purgeTask = 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));
Intent intent = new Intent();
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
setResult(Activity.RESULT_OK, intent);
finish();
}
});
} else {
if (cardProtocol.getError() instanceof CardProtocol.TangemException_InvalidPIN) {
progressBar.post(new Runnable() {
@Override
public void run() {
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
}
});
progressBar.postDelayed(new Runnable() {
@Override
public void run() {
try {
progressBar.setProgress(0);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
progressBar.setVisibility(View.INVISIBLE);
Intent intent = new Intent();
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
intent.putExtra("message", "Cannot erase wallet. Make sure you enter correct PIN2!");
setResult(RESULT_INVALID_PIN, intent);
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}, 500);
return;
} else {
progressBar.post(new Runnable() {
@Override
public void run() {
if (cardProtocol.getError() instanceof CardProtocol.TangemException_ExtendedLengthNotSupported) {
if (!NoExtendedLengthSupportDialog.allreadyShowed) {
new NoExtendedLengthSupportDialog().show(getFragmentManager(), "NoExtendedLengthSupportDialog");
}
} else {
Toast.makeText(getBaseContext(), "Try to scan again", Toast.LENGTH_LONG).show();
}
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
}
});
}
}
}
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() {
purgeTask = 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);
}
@Override
public void OnReadWait(final int msec) {
WaitSecurityDelayDialog.OnReadWait(this, msec);
}
@Override
public void OnReadBeforeRequest(int timeout) {
WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout);
}
@Override
public void OnReadAfterRequest() {
WaitSecurityDelayDialog.onReadAfterRequest(this);
}
}

View file

@ -1,90 +1,90 @@
package com.tangem.wallet;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.google.zxing.Result;
import me.dm7.barcodescanner.zxing.ZXingScannerView;
public class QRScanActivity extends AppCompatActivity implements ZXingScannerView.ResultHandler{
private ZXingScannerView mScannerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_qrscan);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
Log.e("QRScanActivity","User hasn't granted permission to use camera");
ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.CAMERA}, 1);
}else {
runScanner();
}
}
void runScanner()
{
mScannerView = new ZXingScannerView(this); // Programmatically initialize the scanner view
setContentView(mScannerView);
mScannerView.setResultHandler(this); // Register ourselves as a handler for scan results.
mScannerView.startCamera();
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i("QRScanActivity","permission was granted");
// permission was granted, yay! Do the
// contacts-related task you need to do.
runScanner();
} else {
Log.e("QRScanActivity","permission denied");
setResult(Activity.RESULT_CANCELED);
finish();
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
@Override
public void handleResult(Result result) {
Intent data=new Intent();
data.putExtra("QRCode", result.getText());
setResult(Activity.RESULT_OK, data);
finish();
}
@Override
protected void onPause() {
super.onPause();
if( mScannerView!=null ) mScannerView.stopCamera(); // Stop camera on pause
}
@Override
protected void onResume() {
super.onResume();
if( mScannerView!=null ) mScannerView.startCamera();
}
}
package com.tangem.presentation.activity;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.google.zxing.Result;
import me.dm7.barcodescanner.zxing.ZXingScannerView;
public class QRScanActivity extends AppCompatActivity implements ZXingScannerView.ResultHandler{
private ZXingScannerView mScannerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_qrscan);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
Log.e("QRScanActivity","User hasn't granted permission to use camera");
ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.CAMERA}, 1);
}else {
runScanner();
}
}
void runScanner()
{
mScannerView = new ZXingScannerView(this); // Programmatically initialize the scanner view
setContentView(mScannerView);
mScannerView.setResultHandler(this); // Register ourselves as a handler for scan results.
mScannerView.startCamera();
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i("QRScanActivity","permission was granted");
// permission was granted, yay! Do the
// contacts-related task you need to do.
runScanner();
} else {
Log.e("QRScanActivity","permission denied");
setResult(Activity.RESULT_CANCELED);
finish();
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
@Override
public void handleResult(Result result) {
Intent data=new Intent();
data.putExtra("QRCode", result.getText());
setResult(Activity.RESULT_OK, data);
finish();
}
@Override
protected void onPause() {
super.onPause();
if( mScannerView!=null ) mScannerView.stopCamera(); // Stop camera on pause
}
@Override
protected void onResume() {
super.onResume();
if( mScannerView!=null ) mScannerView.startCamera();
}
}

View file

@ -1,4 +1,4 @@
package com.tangem.wallet;
package com.tangem.presentation.activity;
import android.Manifest;
import android.annotation.SuppressLint;
@ -27,6 +27,10 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.tangem.cardReader.NfcManager;
import com.tangem.wallet.FingerprintHelper;
import com.tangem.wallet.PINStorage;
import com.tangem.wallet.R;
import com.tangem.wallet.Tangem_Card;
import java.io.IOException;
import java.security.KeyStore;

View file

@ -1,4 +1,4 @@
package com.tangem.wallet;
package com.tangem.presentation.activity;
import android.Manifest;
import android.annotation.SuppressLint;
@ -23,6 +23,10 @@ import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import com.tangem.wallet.FingerprintHelper;
import com.tangem.wallet.PINStorage;
import com.tangem.wallet.R;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;

View file

@ -1,31 +1,33 @@
package com.tangem.wallet;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
public class SelectBlockchainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_blockchain);
// Spinner spBlockchain = (Spinner) findViewById(R.id.spBlockchain);
// ArrayAdapter<Blockchain> adapter = new ArrayAdapter<Blockchain>(this, android.R.layout.simple_spinner_item, Blockchain.values());
// spBlockchain.setAdapter(adapter);
// spBlockchain.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
// @Override
// public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// Intent intent = new Intent();
// intent.putExtra("blockchain", Blockchain.values()[position].toString());
// setResult(RESULT_OK, intent);
// finish();
// }
//
// @Override
// public void onNothingSelected(AdapterView<?> parent) {
//
// }
// });
}
}
package com.tangem.presentation.activity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.tangem.wallet.R;
public class SelectBlockchainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_blockchain);
// Spinner spBlockchain = (Spinner) findViewById(R.id.spBlockchain);
// ArrayAdapter<Blockchain> adapter = new ArrayAdapter<Blockchain>(this, android.R.layout.simple_spinner_item, Blockchain.values());
// spBlockchain.setAdapter(adapter);
// spBlockchain.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
// @Override
// public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// Intent intent = new Intent();
// intent.putExtra("blockchain", Blockchain.values()[position].toString());
// setResult(RESULT_OK, intent);
// finish();
// }
//
// @Override
// public void onNothingSelected(AdapterView<?> parent) {
//
// }
// });
}
}

View file

@ -1,208 +1,219 @@
package com.tangem.wallet;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.ProgressBar;
import android.widget.Toast;
import org.json.JSONException;
import org.json.JSONObject;
import java.math.BigInteger;
import java.util.List;
public class SendTransactionActivity extends AppCompatActivity {
ProgressBar progressBar;
private Tangem_Card mCard;
private String tx;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_send_transaction);
MainActivity.commonInit(getApplicationContext());
progressBar = findViewById(R.id.progressBar);
Intent intent = getIntent();
mCard = new Tangem_Card(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(intent.getExtras().getBundle("Card"));
tx = intent.getStringExtra("TX");
CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
if (mCard.getBlockchain() == Blockchain.Ethereum || mCard.getBlockchain() == Blockchain.EthereumTestNet || mCard.getBlockchain() == Blockchain.Token) {
ETHRequestTask task = new ETHRequestTask(mCard.getBlockchain());
Infura_Request req = Infura_Request.SendTransaction(mCard.getWallet(), tx);
req.setID(67);
req.setBlockchain(mCard.getBlockchain());
task.execute(req);
} else if (mCard.getBlockchain() == Blockchain.Bitcoin || mCard.getBlockchain() == Blockchain.BitcoinTestNet ) {
String nodeAddress = engine.GetNode(mCard);
int nodePort = engine.GetNodePort(mCard);
ConnectTask connectTask = new ConnectTask(nodeAddress, nodePort);
connectTask.execute(Electrum_Request.Broadcast(mCard.getWallet(), tx));
}
else if (mCard.getBlockchain() == Blockchain.BitcoinCash || mCard.getBlockchain() == Blockchain.BitcoinCashTestNet ) {
String nodeAddress = engine.GetNode(mCard);
int nodePort = engine.GetNodePort(mCard);
ConnectTask connectTask = new ConnectTask(nodeAddress, nodePort);
connectTask.execute(Electrum_Request.Broadcast(mCard.getWallet(), tx));
}
}
@Override
public boolean onKeyDown(int keycode, KeyEvent e) {
switch (keycode) {
case KeyEvent.KEYCODE_BACK:
Toast.makeText(getBaseContext(),"Please wait while the payment is sent...",Toast.LENGTH_LONG).show();
return true;
}
return super.onKeyDown(keycode, e);
}
void FinishWithError(String Message) {
Intent intent = new Intent();
intent.putExtra("message", "Failed to send transaction. Try again.");
setResult(MainActivity.RESULT_CANCELED, intent);
finish();
}
void FinishWithSuccess() {
Intent intent = new Intent();
intent.putExtra("message", "Transaction has been successfully signed and sent to blockchain node. Wallet balance will be updated in a while");
setResult(MainActivity.RESULT_OK, intent);
finish();
}
private class ETHRequestTask extends Infura_Task {
ETHRequestTask(Blockchain blockchain){
super(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_SendRawTransaction)) {
try {
String hashTX = "";
try {
String tmp = request.getResultString();
hashTX = tmp;
}catch(JSONException e)
{
JSONObject msg = request.getAnswer();
JSONObject err = msg.getJSONObject("error");
hashTX = err.getString("message");
LastSignStorage.setLastMessage(mCard.getWallet(), hashTX);
FinishWithError(hashTX);
return;
}
try {
if (hashTX.startsWith("0x") || hashTX.startsWith("0X")) {
hashTX = hashTX.substring(2);
}
BigInteger bigInt = new BigInteger(hashTX, 16); //TODO: очень плохой способ
LastSignStorage.setTxWasSend(mCard.getWallet());
LastSignStorage.setLastMessage(mCard.getWallet(), "");
BigInteger nonce = mCard.GetConfirmTXCount();
nonce.add(BigInteger.valueOf(1));
mCard.SetConfirmTXCount(nonce);
Log.e("TX_RESULT", hashTX);
FinishWithSuccess();
}catch(Exception e)
{
FinishWithError(hashTX);
}
} catch (JSONException e) {
e.printStackTrace();
FinishWithError(e.toString());
}
}
} else if (request.error != null) {
FinishWithError(request.error);
}
} catch (JSONException e) {
e.printStackTrace();
FinishWithError(e.toString());
}
}
}
}
private class ConnectTask extends Electrum_Task {
public ConnectTask(String host, int port) {
super(host, port);
}
public ConnectTask(String host, int port, SharedData sharedData) {
super(host, port, sharedData);
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(List<Electrum_Request> requests) {
super.onPostExecute(requests);
CoinEngine engine = CoinEngineFactory.Create(Blockchain.Bitcoin);
for (Electrum_Request request : requests) {
try {
if (request.error == null) {
if (request.isMethod(Electrum_Request.METHOD_SendTransaction)) {
try {
String hashTX = request.getResultString();
try
{
LastSignStorage.setLastMessage(mCard.getWallet(), hashTX);
if (hashTX.startsWith("0x") || hashTX.startsWith("0X")) {
hashTX = hashTX.substring(2);
}
BigInteger bigInt = new BigInteger(hashTX, 16); //TODO: очень плохой способ
LastSignStorage.setTxWasSend(mCard.getWallet());
LastSignStorage.setLastMessage(mCard.getWallet(), "");
Log.e("TX_RESULT", hashTX);
FinishWithSuccess();
}catch(Exception e)
{
engine.SwitchNode(null);
FinishWithError(hashTX);
return;
}
} catch (JSONException e) {
e.printStackTrace();
engine.SwitchNode(null);
FinishWithError(e.toString());
}
}
} else if (request.error != null) {
engine.SwitchNode(null);
FinishWithError(request.error);
}
} catch (JSONException e) {
e.printStackTrace();
engine.SwitchNode(null);
FinishWithError(e.toString());
}
}
}
}
}
package com.tangem.presentation.activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.tangem.wallet.Blockchain;
import com.tangem.wallet.CoinEngine;
import com.tangem.wallet.CoinEngineFactory;
import com.tangem.wallet.Electrum_Request;
import com.tangem.wallet.Electrum_Task;
import com.tangem.wallet.Infura_Request;
import com.tangem.wallet.Infura_Task;
import com.tangem.wallet.LastSignStorage;
import com.tangem.wallet.R;
import com.tangem.wallet.SharedData;
import com.tangem.wallet.Tangem_Card;
import org.json.JSONException;
import org.json.JSONObject;
import java.math.BigInteger;
import java.util.List;
public class SendTransactionActivity extends AppCompatActivity {
ProgressBar progressBar;
private Tangem_Card mCard;
private String tx;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_send_transaction);
MainActivity.commonInit(getApplicationContext());
progressBar = findViewById(R.id.progressBar);
Intent intent = getIntent();
mCard = new Tangem_Card(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(intent.getExtras().getBundle("Card"));
tx = intent.getStringExtra("TX");
CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
if (mCard.getBlockchain() == Blockchain.Ethereum || mCard.getBlockchain() == Blockchain.EthereumTestNet || mCard.getBlockchain() == Blockchain.Token) {
ETHRequestTask task = new ETHRequestTask(mCard.getBlockchain());
Infura_Request req = Infura_Request.SendTransaction(mCard.getWallet(), tx);
req.setID(67);
req.setBlockchain(mCard.getBlockchain());
task.execute(req);
} else if (mCard.getBlockchain() == Blockchain.Bitcoin || mCard.getBlockchain() == Blockchain.BitcoinTestNet ) {
String nodeAddress = engine.GetNode(mCard);
int nodePort = engine.GetNodePort(mCard);
ConnectTask connectTask = new ConnectTask(nodeAddress, nodePort);
connectTask.execute(Electrum_Request.Broadcast(mCard.getWallet(), tx));
}
else if (mCard.getBlockchain() == Blockchain.BitcoinCash || mCard.getBlockchain() == Blockchain.BitcoinCashTestNet ) {
String nodeAddress = engine.GetNode(mCard);
int nodePort = engine.GetNodePort(mCard);
ConnectTask connectTask = new ConnectTask(nodeAddress, nodePort);
connectTask.execute(Electrum_Request.Broadcast(mCard.getWallet(), tx));
}
}
@Override
public boolean onKeyDown(int keycode, KeyEvent e) {
switch (keycode) {
case KeyEvent.KEYCODE_BACK:
Toast.makeText(getBaseContext(),"Please wait while the payment is sent...",Toast.LENGTH_LONG).show();
return true;
}
return super.onKeyDown(keycode, e);
}
void FinishWithError(String Message) {
Intent intent = new Intent();
intent.putExtra("message", "Failed to send transaction. Try again.");
setResult(MainActivity.RESULT_CANCELED, intent);
finish();
}
void FinishWithSuccess() {
Intent intent = new Intent();
intent.putExtra("message", "Transaction has been successfully signed and sent to blockchain node. Wallet balance will be updated in a while");
setResult(MainActivity.RESULT_OK, intent);
finish();
}
private class ETHRequestTask extends Infura_Task {
ETHRequestTask(Blockchain blockchain){
super(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_SendRawTransaction)) {
try {
String hashTX = "";
try {
String tmp = request.getResultString();
hashTX = tmp;
}catch(JSONException e)
{
JSONObject msg = request.getAnswer();
JSONObject err = msg.getJSONObject("error");
hashTX = err.getString("message");
LastSignStorage.setLastMessage(mCard.getWallet(), hashTX);
FinishWithError(hashTX);
return;
}
try {
if (hashTX.startsWith("0x") || hashTX.startsWith("0X")) {
hashTX = hashTX.substring(2);
}
BigInteger bigInt = new BigInteger(hashTX, 16); //TODO: очень плохой способ
LastSignStorage.setTxWasSend(mCard.getWallet());
LastSignStorage.setLastMessage(mCard.getWallet(), "");
BigInteger nonce = mCard.GetConfirmTXCount();
nonce.add(BigInteger.valueOf(1));
mCard.SetConfirmTXCount(nonce);
Log.e("TX_RESULT", hashTX);
FinishWithSuccess();
}catch(Exception e)
{
FinishWithError(hashTX);
}
} catch (JSONException e) {
e.printStackTrace();
FinishWithError(e.toString());
}
}
} else if (request.error != null) {
FinishWithError(request.error);
}
} catch (JSONException e) {
e.printStackTrace();
FinishWithError(e.toString());
}
}
}
}
private class ConnectTask extends Electrum_Task {
public ConnectTask(String host, int port) {
super(host, port);
}
public ConnectTask(String host, int port, SharedData sharedData) {
super(host, port, sharedData);
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(List<Electrum_Request> requests) {
super.onPostExecute(requests);
CoinEngine engine = CoinEngineFactory.Create(Blockchain.Bitcoin);
for (Electrum_Request request : requests) {
try {
if (request.error == null) {
if (request.isMethod(Electrum_Request.METHOD_SendTransaction)) {
try {
String hashTX = request.getResultString();
try
{
LastSignStorage.setLastMessage(mCard.getWallet(), hashTX);
if (hashTX.startsWith("0x") || hashTX.startsWith("0X")) {
hashTX = hashTX.substring(2);
}
BigInteger bigInt = new BigInteger(hashTX, 16); //TODO: очень плохой способ
LastSignStorage.setTxWasSend(mCard.getWallet());
LastSignStorage.setLastMessage(mCard.getWallet(), "");
Log.e("TX_RESULT", hashTX);
FinishWithSuccess();
}catch(Exception e)
{
engine.SwitchNode(null);
FinishWithError(hashTX);
return;
}
} catch (JSONException e) {
e.printStackTrace();
engine.SwitchNode(null);
FinishWithError(e.toString());
}
}
} else if (request.error != null) {
engine.SwitchNode(null);
FinishWithError(request.error);
}
} catch (JSONException e) {
e.printStackTrace();
engine.SwitchNode(null);
FinishWithError(e.toString());
}
}
}
}
}

File diff suppressed because one or more lines are too long

View file

@ -1,326 +1,331 @@
package com.tangem.wallet;
import android.app.Activity;
import android.content.Intent;
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.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.NfcManager;
import com.tangem.cardReader.Util;
public class SwapPINActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback, CardProtocol.Notifications {
public static final int RESULT_INVALID_PIN = Activity.RESULT_FIRST_USER;
private Tangem_Card mCard;
private NfcManager mNfcManager;
private static final String logTag = "SwapPIN";
private ProgressBar progressBar;
private SwapPINTask swapPinTask;
private String newPIN, newPIN2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swap_pin);
MainActivity.commonInit(getApplicationContext());
mCard = new Tangem_Card(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
newPIN = getIntent().getStringExtra("newPIN");
newPIN2 = getIntent().getStringExtra("newPIN2");
TextView tvCardID = findViewById(R.id.tvCardID);
tvCardID.setText(mCard.getCIDDescription());
mNfcManager = new NfcManager(this, this);
progressBar = findViewById(R.id.progressBar);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
progressBar.setVisibility(View.INVISIBLE);
}
@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);
Log.v(logTag, "UID: " + sUID);
if (sUID.equals(mCard.getUID())) {
isoDep.setTimeout(mCard.getPauseBeforePIN2() + 65000);
swapPinTask = new SwapPINTask(isoDep, this);
swapPinTask.start();
} else {
Log.d(logTag, "Mismatch card UID (" + sUID + " instead of " + mCard.getUID() + ")");
mNfcManager.IgnoreTag(isoDep.getTag());
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onResume() {
super.onResume();
mNfcManager.onResume();
}
@Override
public void onPause() {
mNfcManager.onPause();
if (swapPinTask != null) {
swapPinTask.cancel(true);
}
super.onPause();
}
@Override
public void onStop() {
// dismiss enable NFC dialog
mNfcManager.onStop();
if (swapPinTask != null) {
swapPinTask.cancel(true);
}
super.onStop();
}
private class SwapPINTask extends Thread {
IsoDep mIsoDep;
CardProtocol.Notifications mNotifications;
private boolean isCancelled = false;
SwapPINTask(IsoDep isoDep, CardProtocol.Notifications notifications) {
mIsoDep = isoDep;
mNotifications = notifications;
}
@Override
public void run() {
if (mIsoDep == null) {
return;
}
CardProtocol protocol = new CardProtocol(getBaseContext(), mIsoDep, mCard, mNotifications);
mNotifications.OnReadStart(protocol);
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 {
mNotifications.OnReadProgress(protocol, 5);
Log.i("SwapTask", "[-- Start swap pin --]");
if (isCancelled) return;
if (mCard.getPauseBeforePIN2() > 0) {
mNotifications.OnReadWait(mCard.getPauseBeforePIN2());
}
// try {
protocol.run_SwapPIN(PINStorage.getPIN2(), newPIN, newPIN2, false);
protocol.setPIN(newPIN);
mCard.setPIN(newPIN);
// } finally {
// mNotifications.OnReadWait(0);
// }
mNotifications.OnReadProgress(protocol, 50);
protocol.run_Read();
mNotifications.OnReadProgress(protocol, 100);
} finally {
mNfcManager.IgnoreTag(mIsoDep.getTag());
}
} catch (Exception e) {
e.printStackTrace();
protocol.setError(e);
} finally {
Log.i("SwapPINTask", "[-- Finish purge --]");
mNotifications.OnReadFinish(protocol);
}
}
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();
}
}
}
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) {
swapPinTask = 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));
Intent intent = new Intent();
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
setResult(Activity.RESULT_OK, intent);
finish();
}
});
} else if (cardProtocol.getError() instanceof CardProtocol.TangemException_InvalidPIN) {
progressBar.post(new Runnable() {
@Override
public void run() {
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
}
});
progressBar.postDelayed(new Runnable() {
@Override
public void run() {
try {
progressBar.setProgress(0);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
progressBar.setVisibility(View.INVISIBLE);
Intent intent = new Intent();
intent.putExtra("message", "Cannot change PIN(s). Make sure you enter correct PIN2!");
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
setResult(RESULT_INVALID_PIN, intent);
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}, 500);
return;
} else {
progressBar.post(new Runnable() {
@Override
public void run() {
if (cardProtocol.getError() instanceof CardProtocol.TangemException_ExtendedLengthNotSupported) {
if (!NoExtendedLengthSupportDialog.allreadyShowed) {
new NoExtendedLengthSupportDialog().show(getFragmentManager(), "NoExtendedLengthSupportDialog");
}
} else {
Toast.makeText(getBaseContext(), "Try to scan again", Toast.LENGTH_LONG).show();
}
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
}
});
}
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() {
swapPinTask = 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);
}
@Override
public void OnReadWait(final int msec) {
WaitSecurityDelayDialog.OnReadWait(this, msec);
}
@Override
public void OnReadBeforeRequest(int timeout) {
WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout);
}
@Override
public void OnReadAfterRequest() {
WaitSecurityDelayDialog.onReadAfterRequest(this);
}
}
package com.tangem.presentation.activity;
import android.app.Activity;
import android.content.Intent;
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.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.NfcManager;
import com.tangem.cardReader.Util;
import com.tangem.wallet.NoExtendedLengthSupportDialog;
import com.tangem.wallet.PINStorage;
import com.tangem.wallet.R;
import com.tangem.wallet.Tangem_Card;
import com.tangem.wallet.WaitSecurityDelayDialog;
public class SwapPINActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback, CardProtocol.Notifications {
public static final int RESULT_INVALID_PIN = Activity.RESULT_FIRST_USER;
private Tangem_Card mCard;
private NfcManager mNfcManager;
private static final String logTag = "SwapPIN";
private ProgressBar progressBar;
private SwapPINTask swapPinTask;
private String newPIN, newPIN2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swap_pin);
MainActivity.commonInit(getApplicationContext());
mCard = new Tangem_Card(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
newPIN = getIntent().getStringExtra("newPIN");
newPIN2 = getIntent().getStringExtra("newPIN2");
TextView tvCardID = findViewById(R.id.tvCardID);
tvCardID.setText(mCard.getCIDDescription());
mNfcManager = new NfcManager(this, this);
progressBar = findViewById(R.id.progressBar);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
progressBar.setVisibility(View.INVISIBLE);
}
@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);
Log.v(logTag, "UID: " + sUID);
if (sUID.equals(mCard.getUID())) {
isoDep.setTimeout(mCard.getPauseBeforePIN2() + 65000);
swapPinTask = new SwapPINTask(isoDep, this);
swapPinTask.start();
} else {
Log.d(logTag, "Mismatch card UID (" + sUID + " instead of " + mCard.getUID() + ")");
mNfcManager.IgnoreTag(isoDep.getTag());
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onResume() {
super.onResume();
mNfcManager.onResume();
}
@Override
public void onPause() {
mNfcManager.onPause();
if (swapPinTask != null) {
swapPinTask.cancel(true);
}
super.onPause();
}
@Override
public void onStop() {
// dismiss enable NFC dialog
mNfcManager.onStop();
if (swapPinTask != null) {
swapPinTask.cancel(true);
}
super.onStop();
}
private class SwapPINTask extends Thread {
IsoDep mIsoDep;
CardProtocol.Notifications mNotifications;
private boolean isCancelled = false;
SwapPINTask(IsoDep isoDep, CardProtocol.Notifications notifications) {
mIsoDep = isoDep;
mNotifications = notifications;
}
@Override
public void run() {
if (mIsoDep == null) {
return;
}
CardProtocol protocol = new CardProtocol(getBaseContext(), mIsoDep, mCard, mNotifications);
mNotifications.OnReadStart(protocol);
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 {
mNotifications.OnReadProgress(protocol, 5);
Log.i("SwapTask", "[-- Start swap pin --]");
if (isCancelled) return;
if (mCard.getPauseBeforePIN2() > 0) {
mNotifications.OnReadWait(mCard.getPauseBeforePIN2());
}
// try {
protocol.run_SwapPIN(PINStorage.getPIN2(), newPIN, newPIN2, false);
protocol.setPIN(newPIN);
mCard.setPIN(newPIN);
// } finally {
// mNotifications.OnReadWait(0);
// }
mNotifications.OnReadProgress(protocol, 50);
protocol.run_Read();
mNotifications.OnReadProgress(protocol, 100);
} finally {
mNfcManager.IgnoreTag(mIsoDep.getTag());
}
} catch (Exception e) {
e.printStackTrace();
protocol.setError(e);
} finally {
Log.i("SwapPINTask", "[-- Finish purge --]");
mNotifications.OnReadFinish(protocol);
}
}
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();
}
}
}
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) {
swapPinTask = 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));
Intent intent = new Intent();
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
setResult(Activity.RESULT_OK, intent);
finish();
}
});
} else if (cardProtocol.getError() instanceof CardProtocol.TangemException_InvalidPIN) {
progressBar.post(new Runnable() {
@Override
public void run() {
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
}
});
progressBar.postDelayed(new Runnable() {
@Override
public void run() {
try {
progressBar.setProgress(0);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.DKGRAY));
progressBar.setVisibility(View.INVISIBLE);
Intent intent = new Intent();
intent.putExtra("message", "Cannot change PIN(s). Make sure you enter correct PIN2!");
intent.putExtra("UID", cardProtocol.getCard().getUID());
intent.putExtra("Card", cardProtocol.getCard().getAsBundle());
setResult(RESULT_INVALID_PIN, intent);
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}, 500);
return;
} else {
progressBar.post(new Runnable() {
@Override
public void run() {
if (cardProtocol.getError() instanceof CardProtocol.TangemException_ExtendedLengthNotSupported) {
if (!NoExtendedLengthSupportDialog.allreadyShowed) {
new NoExtendedLengthSupportDialog().show(getFragmentManager(), "NoExtendedLengthSupportDialog");
}
} else {
Toast.makeText(getBaseContext(), "Try to scan again", Toast.LENGTH_LONG).show();
}
progressBar.setProgress(100);
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
}
});
}
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() {
swapPinTask = 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);
}
@Override
public void OnReadWait(final int msec) {
WaitSecurityDelayDialog.OnReadWait(this, msec);
}
@Override
public void OnReadBeforeRequest(int timeout) {
WaitSecurityDelayDialog.onReadBeforeRequest(this, timeout);
}
@Override
public void OnReadAfterRequest() {
WaitSecurityDelayDialog.onReadAfterRequest(this);
}
}

View file

@ -1,28 +1,30 @@
package com.tangem.wallet;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
public class VerifyCardActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_verify_card);
MainActivity.commonInit(getApplicationContext());
}
@Override
public void onBackPressed() {
//super.onBackPressed();
VerifyCardActivityFragment verifyCardActivityFragment= (VerifyCardActivityFragment) getSupportFragmentManager().findFragmentById(R.id.verify_card_fragment);
Intent data= verifyCardActivityFragment.prepareResultIntent();
data.putExtra("modification", "update");
setResult(Activity.RESULT_OK, data);
finish();
}
}
package com.tangem.presentation.activity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.tangem.wallet.R;
import com.tangem.wallet.VerifyCardActivityFragment;
public class VerifyCardActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_verify_card);
MainActivity.commonInit(getApplicationContext());
}
@Override
public void onBackPressed() {
//super.onBackPressed();
VerifyCardActivityFragment verifyCardActivityFragment = (VerifyCardActivityFragment) getSupportFragmentManager().findFragmentById(R.id.verify_card_fragment);
Intent data = verifyCardActivityFragment.prepareResultIntent();
data.putExtra("modification", "update");
setResult(Activity.RESULT_OK, data);
finish();
}
}

View file

@ -27,7 +27,7 @@ public class Electrum_Task extends AsyncTask<Electrum_Request, Integer, List<Ele
OutputStreamWriter out;
BufferedReader in;
SharedData sharedCounter = null;
public SharedData sharedCounter = null;
public Electrum_Task(String host, int port) {

View file

@ -15,7 +15,7 @@ import java.util.List;
public class Fee_Task extends AsyncTask<Fee_Request, Void, List<Fee_Request>> {
SharedData sharedCounter = null;
public SharedData sharedCounter = null;
public Fee_Task(SharedData sharedData)
{

View file

@ -35,7 +35,7 @@ public class FingerprintHelper extends FingerprintManager.AuthenticationCallback
cancellationSignal.cancel();
}
interface FingerprintHelperListener {
public interface FingerprintHelperListener {
public void authenticationFailed(String error);
public void authenticationSucceeded(FingerprintManager.AuthenticationResult result);
}

View file

@ -6,7 +6,6 @@ import android.preference.PreferenceManager;
import android.util.ArrayMap;
import android.util.ArraySet;
import java.lang.reflect.Array;
import java.util.Date;
import java.util.Map;
import java.util.Set;
@ -24,7 +23,7 @@ public class LastSignStorage {
private static Map<String, String> txCol = new ArrayMap<>();
private static Map<String, String> txCompleteCol = new ArrayMap<>();
static void Init(Context context) {
public static void Init(Context context) {
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
cards=sharedPreferences.getStringSet("LastSign_Cards", cards);
for (int i = 0; i < cards.size(); i++) {

View file

@ -42,6 +42,12 @@ import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.NfcManager;
import com.tangem.cardReader.Util;
import com.tangem.presentation.activity.CreateNewWalletActivity;
import com.tangem.presentation.activity.PreparePaymentActivity;
import com.tangem.presentation.activity.PurgeActivity;
import com.tangem.presentation.activity.RequestPINActivity;
import com.tangem.presentation.activity.SwapPINActivity;
import com.tangem.presentation.activity.VerifyCardActivity;
import org.json.JSONArray;
import org.json.JSONException;

View file

@ -27,6 +27,10 @@ import android.widget.Toast;
import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.NfcManager;
import com.tangem.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 org.json.JSONArray;
import org.json.JSONException;

View file

@ -4,7 +4,6 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Base64;
import android.util.Log;
import com.tangem.cardReader.CardProtocol;
@ -18,11 +17,11 @@ import javax.crypto.Cipher;
* Global PIN Storage
*/
class PINStorage {
public class PINStorage {
private static String mSavedPIN, mUserPIN, mLastUsedPIN, mEncryptedPIN, mPIN2;
private static SharedPreferences sharedPreferences=null;
static void Init(Context context) {
public static void Init(Context context) {
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
mSavedPIN = sharedPreferences.getString("SavedPIN", null);
mUserPIN = null;
@ -46,15 +45,15 @@ class PINStorage {
mLastUsedPIN = PIN;
}
static void setUserPIN(String PIN) {
public static void setUserPIN(String PIN) {
mUserPIN = PIN;
}
static void setPIN2(String PIN) {
public static void setPIN2(String PIN) {
mPIN2 = PIN;
}
static void savePIN(String PIN) {
public static void savePIN(String PIN) {
mSavedPIN = PIN;
if (mSavedPIN != null && !mSavedPIN.isEmpty()) {
SharedPreferences.Editor editor = sharedPreferences.edit();
@ -65,7 +64,7 @@ class PINStorage {
}
}
static void deletePIN() {
public static void deletePIN() {
SharedPreferences.Editor editor = sharedPreferences.edit();
if (mSavedPIN != null && mLastUsedPIN != null && mSavedPIN.equals(mLastUsedPIN)) {
mLastUsedPIN = null;
@ -75,7 +74,7 @@ class PINStorage {
editor.apply();
}
static void saveEncryptedPIN(Cipher cipher, String PIN) {
public static void saveEncryptedPIN(Cipher cipher, String PIN) {
try {
byte[] iv = cipher.getIV();
byte[] bytes = cipher.doFinal(PIN.getBytes());
@ -93,14 +92,14 @@ class PINStorage {
}
}
static byte[] loadEncryptedIV() {
public static byte[] loadEncryptedIV() {
String sIV = sharedPreferences.getString("EncryptedIV", "");
// Log.d("PINStorage", String.format("loadEncryptedIV: %s",sIV));
return Base64.decode(sIV, Base64.NO_WRAP);
}
static String loadEncryptedPIN(Cipher cipher) {
public static String loadEncryptedPIN(Cipher cipher) {
String encryptedPIN = sharedPreferences.getString("EncryptedPIN", null);
try {
@ -114,11 +113,11 @@ class PINStorage {
return mEncryptedPIN;
}
static boolean haveEncryptedPIN() {
public static boolean haveEncryptedPIN() {
return sharedPreferences.getString("EncryptedPIN", null) != null;
}
static void deleteEncryptedPIN() {
public static void deleteEncryptedPIN() {
if (mEncryptedPIN != null && mLastUsedPIN != null && mEncryptedPIN.equals(mLastUsedPIN)) {
mLastUsedPIN = null;
}
@ -129,7 +128,7 @@ class PINStorage {
editor.apply();
}
static void saveEncryptedPIN2(Cipher cipher, String PIN) {
public static void saveEncryptedPIN2(Cipher cipher, String PIN) {
try {
byte[] iv = cipher.getIV();
byte[] bytes = cipher.doFinal(PIN.getBytes());
@ -147,14 +146,14 @@ class PINStorage {
}
}
static byte[] loadEncryptedIV2() {
public static byte[] loadEncryptedIV2() {
String sIV = sharedPreferences.getString("EncryptedIV2", "");
// Log.d("PINStorage", String.format("loadEncryptedIV: %s",sIV));
return Base64.decode(sIV, Base64.NO_WRAP);
}
static String loadEncryptedPIN2(Cipher cipher) {
public static String loadEncryptedPIN2(Cipher cipher) {
String encryptedPIN = sharedPreferences.getString("EncryptedPIN2", null);
try {
@ -168,11 +167,11 @@ class PINStorage {
return mPIN2;
}
static boolean haveEncryptedPIN2() {
public static boolean haveEncryptedPIN2() {
return sharedPreferences.getString("EncryptedPIN2", null) != null;
}
static void deleteEncryptedPIN2() {
public static void deleteEncryptedPIN2() {
mPIN2 = null;
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove("EncryptedPIN2");

View file

@ -13,6 +13,7 @@ public class SharedData
public AtomicInteger requestCounter;
public int allRequest;
public AtomicInteger errorRequest;
public SharedData(int requstCount)
{
allRequest = requstCount;

File diff suppressed because one or more lines are too long

View file

@ -21,7 +21,7 @@ public class VerifyCardTask extends Thread {
private Tangem_Card mCard;
private NfcManager mNfcManager;
VerifyCardTask(Context context, Tangem_Card card, NfcManager nfcManager, IsoDep isoDep, CardProtocol.Notifications notifications) {
public VerifyCardTask(Context context, Tangem_Card card, NfcManager nfcManager, IsoDep isoDep, CardProtocol.Notifications notifications) {
mCard = card;
mContext = context;
mIsoDep = isoDep;