Updated on 2026-08-14

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

1
.gitignore vendored
View file

@ -10,3 +10,4 @@
.externalNativeBuild .externalNativeBuild
app/libs/ app/libs/
.idea/vcs.xml .idea/vcs.xml
.idea/caches

Binary file not shown.

View file

@ -1,24 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tangem.wallet" package="com.tangem.wallet">
android:versionCode="0"
android:versionName="0">
<uses-feature <uses-feature
android:name="android.hardware.nfc" android:name="android.hardware.nfc"
android:required="true" /> android:required="true"/>
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.NFC"/>
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.USE_FINGERPRINT" /> <uses-permission android:name="android.permission.USE_FINGERPRINT"/>
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA"/>
<!--<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />-->
<uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus" /> <uses-feature android:name="android.hardware.camera.autofocus"/>
<application <application
android:name="com.tangem.AppController"
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
@ -31,106 +29,121 @@
android:authorities="com.tangem.wallet.LogFileProvider" android:authorities="com.tangem.wallet.LogFileProvider"
android:enabled="true" android:enabled="true"
android:exported="false" android:exported="false"
android:grantUriPermissions="true" /> android:grantUriPermissions="true"/>
<activity <activity
android:name=".LogoActivity" android:name="com.tangem.presentation.activity.LogoActivity"
android:label="@string/title_activity_main" android:label="@string/title_activity_main"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name=".RequestPINActivity" android:name="com.tangem.presentation.activity.MainActivity"
android:label="@string/title_activity_main" android:label="@string/title_activity_main"
android:launchMode="singleTask"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
</activity>
<activity
android:name=".EmptyWalletActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".SelectBlockchainActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".SavePINActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"
android:launchMode="singleTask">
<intent-filter> <intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" /> <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.DEFAULT" />
<data <data
android:host="www.tangem.com" android:host="www.tangem.com"
android:scheme="http" /> android:scheme="http"/>
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" /> <action android:name="android.nfc.action.TECH_DISCOVERED"/>
</intent-filter> </intent-filter>
<meta-data <meta-data
android:name="android.nfc.action.TECH_DISCOVERED" android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" /> android:resource="@xml/nfc_tech_filter"/>
</activity> </activity>
<activity <activity
android:name=".CardInfoActivity" android:name="com.tangem.presentation.activity.RequestPINActivity"
android:label="@string/title_activity_card_info"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".LoadedWalletActivity"
android:label="@string/title_activity_loaded_wallet"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".VerifyCardActivity"
android:label="@string/title_activity_loaded_wallet"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".CreateNewWalletActivity"
android:label="@string/title_activity_main" android:label="@string/title_activity_main"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar"/>
<activity <activity
android:name=".PreparePaymentActivity" android:name="com.tangem.presentation.activity.EmptyWalletActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar"/>
<activity <activity
android:name=".ConfirmPaymentActivity" android:name="com.tangem.presentation.activity.SelectBlockchainActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar"/>
<activity <activity
android:name=".SignPaymentActivity" android:name="com.tangem.presentation.activity.SavePINActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar"/>
<activity <activity
android:name=".PurgeActivity" android:name="com.tangem.presentation.activity.CardInfoActivity"
android:label="@string/title_activity_card_info"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar"/>
<activity <activity
android:name=".SwapPINActivity" android:name="com.tangem.presentation.activity.LoadedWalletActivity"
android:label="@string/title_activity_loaded_wallet"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar"/>
<activity <activity
android:name=".QRScanActivity" android:name="com.tangem.presentation.activity.VerifyCardActivity"
android:label="@string/title_activity_loaded_wallet"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar"/>
<activity <activity
android:name=".SendTransactionActivity" android:name="com.tangem.presentation.activity.CreateNewWalletActivity"
android:label="@string/title_activity_main"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" /> android:theme="@style/AppTheme.NoActionBar"/>
<activity
android:name="com.tangem.presentation.activity.PreparePaymentActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"/>
<activity
android:name="com.tangem.presentation.activity.ConfirmPaymentActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"/>
<activity
android:name="com.tangem.presentation.activity.SignPaymentActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"/>
<activity
android:name="com.tangem.presentation.activity.PurgeActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"/>
<activity
android:name="com.tangem.presentation.activity.SwapPINActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"/>
<activity
android:name="com.tangem.presentation.activity.QRScanActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"/>
<activity
android:name="com.tangem.presentation.activity.SendTransactionActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"/>
</application> </application>
</manifest> </manifest>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,4 +1,4 @@
package com.tangem.wallet; package com.tangem.presentation.activity;
import android.Manifest; import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@ -27,6 +27,10 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.tangem.cardReader.NfcManager; 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.io.IOException;
import java.security.KeyStore; import java.security.KeyStore;

View file

@ -1,4 +1,4 @@
package com.tangem.wallet; package com.tangem.presentation.activity;
import android.Manifest; import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@ -23,6 +23,10 @@ import android.widget.CheckBox;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; 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.io.IOException;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.KeyStoreException; import java.security.KeyStoreException;

View file

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

View file

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

File diff suppressed because one or more lines are too long

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -42,6 +42,12 @@ import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.tangem.cardReader.CardProtocol; import com.tangem.cardReader.CardProtocol;
import com.tangem.cardReader.NfcManager; import com.tangem.cardReader.NfcManager;
import com.tangem.cardReader.Util; 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.JSONArray;
import org.json.JSONException; import org.json.JSONException;

View file

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

View file

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

View file

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

File diff suppressed because one or more lines are too long

View file

@ -21,7 +21,7 @@ public class VerifyCardTask extends Thread {
private Tangem_Card mCard; private Tangem_Card mCard;
private NfcManager mNfcManager; 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; mCard = card;
mContext = context; mContext = context;
mIsoDep = isoDep; mIsoDep = isoDep;

View file

@ -6,7 +6,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
tools:context="com.tangem.wallet.CardInfoActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.CardInfoActivity">
<android.support.design.widget.AppBarLayout <android.support.design.widget.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appbar"

View file

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.tangem.wallet.ConfirmPaymentActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.ConfirmPaymentActivity">
<TextView <TextView
android:id="@+id/textView" android:id="@+id/textView"

View file

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.tangem.wallet.CreateNewWalletActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.CreateNewWalletActivity">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View file

@ -7,7 +7,7 @@
android:background="@color/white" android:background="@color/white"
android:orientation="vertical" android:orientation="vertical"
android:padding="0dp" android:padding="0dp"
tools:context="com.tangem.wallet.EmptyWalletActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.EmptyWalletActivity">
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.tangem.wallet.LoadedWalletActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.LoadedWalletActivity">
<!--<android.support.design.widget.AppBarLayout--> <!--<android.support.design.widget.AppBarLayout-->
<!--android:layout_width="match_parent"--> <!--android:layout_width="match_parent"-->

View file

@ -5,7 +5,7 @@
android:background="#FFFFFF" android:background="#FFFFFF"
android:gravity="bottom" android:gravity="bottom"
android:orientation="vertical" android:orientation="vertical"
tools:context="com.tangem.wallet.LogoActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.LogoActivity">
<ImageView <ImageView
android:id="@+id/imgLogo" android:id="@+id/imgLogo"

View file

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.tangem.wallet.MainActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.MainActivity">
<!--<ImageView--> <!--<ImageView-->
<!--android:id="@+id/ivTap"--> <!--android:id="@+id/ivTap"-->

View file

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.tangem.wallet.PreparePaymentActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.PreparePaymentActivity">
<TextView <TextView
android:id="@+id/textView" android:id="@+id/textView"

View file

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.tangem.wallet.PurgeActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.PurgeActivity">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View file

@ -3,6 +3,6 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.tangem.wallet.QRScanActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.QRScanActivity">
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>

View file

@ -4,7 +4,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:orientation="vertical" android:orientation="vertical"
tools:context="com.tangem.wallet.RequestPINActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.RequestPINActivity">
<!--android:paddingBottom="@dimen/activity_vertical_margin"--> <!--android:paddingBottom="@dimen/activity_vertical_margin"-->
<!--android:paddingLeft="@dimen/activity_horizontal_margin"--> <!--android:paddingLeft="@dimen/activity_horizontal_margin"-->
<!--android:paddingRight="@dimen/activity_horizontal_margin"--> <!--android:paddingRight="@dimen/activity_horizontal_margin"-->

View file

@ -4,7 +4,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:orientation="vertical" android:orientation="vertical"
tools:context="com.tangem.wallet.SavePINActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.SavePINActivity">
<!--android:paddingBottom="@dimen/activity_vertical_margin"--> <!--android:paddingBottom="@dimen/activity_vertical_margin"-->
<!--android:paddingLeft="@dimen/activity_horizontal_margin"--> <!--android:paddingLeft="@dimen/activity_horizontal_margin"-->
<!--android:paddingRight="@dimen/activity_horizontal_margin"--> <!--android:paddingRight="@dimen/activity_horizontal_margin"-->

View file

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.tangem.wallet.SendTransactionActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.SendTransactionActivity">
<ProgressBar <ProgressBar
android:id="@+id/progressBar" android:id="@+id/progressBar"

View file

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.tangem.wallet.SignPaymentActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.SignPaymentActivity">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View file

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.tangem.wallet.PurgeActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.PurgeActivity">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View file

@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.tangem.wallet.VerifyCardActivity"> tools:context="com.tangem.wallet.com.tangem.presentation.activity.VerifyCardActivity">
<include <include