Updated on 2026-08-14
This commit is contained in:
parent
0374157cad
commit
8c17a8d4f0
48 changed files with 3490 additions and 3417 deletions
4
app/src/main/java/com/tangem/domain/Logic.java
Normal file
4
app/src/main/java/com/tangem/domain/Logic.java
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
package com.tangem.domain;
|
||||
|
||||
public class Logic {
|
||||
}
|
||||
4
app/src/main/java/com/tangem/presentation/Screen.java
Normal file
4
app/src/main/java/com/tangem/presentation/Screen.java
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
package com.tangem.presentation;
|
||||
|
||||
public class Screen {
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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) {
|
||||
//
|
||||
// }
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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++) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue