Updated on 2026-08-14

This commit is contained in:
Tangem 2019-02-07 15:32:05 +03:00
commit 6ccf421860
63 changed files with 874 additions and 1238 deletions

View file

@ -1,106 +0,0 @@
package com.tangem;
import android.app.Application;
import androidx.appcompat.app.AppCompatDelegate;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.tangem.tangemserver.android.data.LocalStorage;
import com.tangem.di.DaggerNavigatorComponent;
import com.tangem.di.DaggerNetworkComponent;
import com.tangem.di.NavigatorComponent;
import com.tangem.di.NetworkComponent;
import com.tangem.tangemcard.data.Issuer;
import com.tangem.tangemcard.android.data.Firmwares;
import com.tangem.tangemcard.android.data.PINStorage;
import com.tangem.tangemcard.data.external.FirmwaresDigestsProvider;
import com.tangem.tangemcard.data.external.PINsProvider;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class App extends Application {
/**
* A singleton instance of the application class for easy access in other places
*/
private static App sInstance;
public App() {
super();
}
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
private static NetworkComponent networkComponent;
private static NavigatorComponent navigatorComponent;
public static NavigatorComponent getNavigatorComponent() {
return navigatorComponent;
}
public static LocalStorage localStorage;
public static PINsProvider pinStorage;
public static FirmwaresDigestsProvider firmwaresStorage;
@Override
public void onCreate() {
super.onCreate();
// initialize the singleton
sInstance = this;
networkComponent = DaggerNetworkComponent.create();
navigatorComponent = buildNavigatorComponent();
// common init
if (PINStorage.needInit())
PINStorage.init(getApplicationContext());
initIssuers();
firmwaresStorage = new Firmwares(getApplicationContext());
localStorage = new LocalStorage(getApplicationContext());
pinStorage = new PINStorage();
}
/**
* @return singleton instance
*/
public static synchronized App getInstance() {
return sInstance;
}
public static NetworkComponent getNetworkComponent() {
return networkComponent;
}
protected NavigatorComponent buildNavigatorComponent() {
return DaggerNavigatorComponent.builder()
.build();
}
public void initIssuers() {
try {
try (InputStream is = getApplicationContext().getAssets().open("issuers.json")) {
try (InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
Type listType = new TypeToken<List<Issuer>>() {
}.getType();
Issuer.fillIssuers(new Gson().fromJson(reader, listType));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,81 @@
package com.tangem
import android.app.Application
import androidx.appcompat.app.AppCompatDelegate
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.tangem.di.DaggerNavigatorComponent
import com.tangem.di.DaggerNetworkComponent
import com.tangem.di.NavigatorComponent
import com.tangem.di.NetworkComponent
import com.tangem.tangemcard.android.data.Firmwares
import com.tangem.tangemcard.android.data.PINStorage
import com.tangem.tangemcard.data.Issuer
import com.tangem.tangemcard.data.external.FirmwaresDigestsProvider
import com.tangem.tangemcard.data.external.PINsProvider
import com.tangem.tangemserver.android.data.LocalStorage
import java.io.InputStreamReader
import java.nio.charset.StandardCharsets
class App : Application() {
companion object {
@get:Synchronized
var instance: App? = null
private set
init {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
}
var networkComponent: NetworkComponent? = null
private set
var navigatorComponent: NavigatorComponent? = null
private set
lateinit var firmwaresStorage: FirmwaresDigestsProvider
lateinit var localStorage: LocalStorage
lateinit var pinStorage: PINsProvider
}
override fun onCreate() {
super.onCreate()
// initialize the singleton
instance = this
networkComponent = DaggerNetworkComponent.create()
navigatorComponent = buildNavigatorComponent()
// common init
if (PINStorage.needInit())
PINStorage.init(applicationContext)
initIssuers()
firmwaresStorage = Firmwares(applicationContext)
localStorage = LocalStorage(applicationContext)
pinStorage = PINStorage()
}
private fun buildNavigatorComponent(): NavigatorComponent {
return DaggerNavigatorComponent.builder()
.build()
}
private fun initIssuers() {
try {
applicationContext.assets.open("issuers.json").use { `is` ->
InputStreamReader(`is`, StandardCharsets.UTF_8).use { reader ->
val listType = object : TypeToken<List<Issuer>>() {
}.type
Issuer.fillIssuers(Gson().fromJson(reader, listType))
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}

View file

@ -51,7 +51,7 @@ public class LogFileProvider extends ContentProvider {
Log.v(LOG_TAG,
"Called with uri: '" + uri + "'." + uri.getLastPathSegment());
// Check incoming Uri against the matcher
// check incoming Uri against the matcher
switch (uriMatcher.match(uri)) {
// If it returns 1 - then it matches the Uri defined in onCreate

View file

@ -226,7 +226,7 @@ public class Logger {
//
// verifyStoragePermissions(activity);
// initLogFile(activity.getApplicationContext());
// t.start();
// t.init();
// } catch (Exception e) {
// e.printStackTrace();
// }
@ -268,7 +268,7 @@ public class Logger {
// //Checks if the app has permission to write to device storage
// //If the app does not has permission then the user will be prompted to grant permissions
// public static void verifyStoragePermissions(Activity activity) {
// // Check if we have write permission
// // check if we have write permission
// int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
//
// if (permission != PackageManager.PERMISSION_GRANTED) {

View file

@ -36,7 +36,7 @@ public class ServerApiCommon {
}
public void requestBtcEstimatedFee(int blockCount) {
EstimatefeeApi estimatefeeApi = App.getNetworkComponent().getRetrofitEstimatefee().create(EstimatefeeApi.class);
EstimatefeeApi estimatefeeApi = App.Companion.getNetworkComponent().getRetrofitEstimatefee().create(EstimatefeeApi.class);
Call<String> call;
switch (blockCount) {
@ -91,7 +91,7 @@ public class ServerApiCommon {
@SuppressLint("CheckResult")
public void requestRateInfo(String cryptoId) {
CoinmarketApi coinmarketApi = App.getNetworkComponent().getRetrofitCoinmarketcap().create(CoinmarketApi.class);
CoinmarketApi coinmarketApi = App.Companion.getNetworkComponent().getRetrofitCoinmarketcap().create(CoinmarketApi.class);
coinmarketApi.getRateInfoList()
.subscribeOn(Schedulers.io())
@ -126,7 +126,7 @@ public class ServerApiCommon {
}
public void requestLastVersion() {
UpdateVersionApi updateVersionApi = App.getNetworkComponent().getRetrofitGithubusercontent().create(UpdateVersionApi.class);
UpdateVersionApi updateVersionApi = App.Companion.getNetworkComponent().getRetrofitGitHubUserContent().create(UpdateVersionApi.class);
Call<ResponseBody> call = updateVersionApi.getLastVersion();
call.enqueue(new Callback<ResponseBody>() {

View file

@ -230,7 +230,7 @@ public class ServerApiElectrum {
private void doElectrumRequestTcp(ElectrumRequest electrumRequest, String host, int port) {
try {
Socket socket = App.getNetworkComponent().getSocket();
Socket socket = App.Companion.getNetworkComponent().getSocket();
socket.setSoTimeout(3000);
Log.i(TAG, "Start process "+electrumRequest.getMethod()+" @ "+host + ":" + port);
socket.connect(new InetSocketAddress(InetAddress.getByName(host), port));
@ -252,18 +252,18 @@ public class ServerApiElectrum {
if( (electrumRequest.getError()!=null && electrumRequest.getError().startsWith(ERROR_STARTS_WITH_CODE_32601)) )
{
// method unknown error???
electrumRequest.setError(App.getInstance().getString(R.string.cannot_obtain_data_from_blockchain));
electrumRequest.setError(App.Companion.getInstance().getString(R.string.cannot_obtain_data_from_blockchain));
electrumRequest.answerData=null;
}
} else {
electrumRequest.setError(App.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_no_answer));
electrumRequest.setError(App.Companion.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_no_answer));
Log.i(TAG, ">> <NULL>");
}
} catch (ConnectException e) {
//e.printStackTrace();
//responseListener.onFail(e.getMessage());
electrumRequest.setError(App.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_no_connection));
electrumRequest.setError(App.Companion.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_no_connection));
Log.e(TAG, "doElectrumRequestTcp " + electrumRequest.getMethod() + " ConnectException " + e.getMessage());
} finally {
Log.i(TAG, "doElectrumRequestTcp " + electrumRequest.getMethod() + " socket.close");
@ -274,13 +274,13 @@ public class ServerApiElectrum {
{
e.printStackTrace();
Log.e(TAG,"Can't close socket");
electrumRequest.setError(App.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_communication_error));
electrumRequest.setError(App.Companion.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_communication_error));
}
}
} catch (IOException e) {
//e.printStackTrace();
//responseListener.onFail(e.getMessage());
electrumRequest.setError(App.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_communication_error));
electrumRequest.setError(App.Companion.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_communication_error));
Log.e(TAG, "doElectrumRequestTcp " + electrumRequest.getMethod() + " IOException " + e.getMessage());
}
}
@ -341,17 +341,17 @@ public class ServerApiElectrum {
if( (electrumRequest.getError()!=null && electrumRequest.getError().startsWith(ERROR_STARTS_WITH_CODE_32601)) )
{
// method unknown error???
electrumRequest.setError(App.getInstance().getString(R.string.cannot_obtain_data_from_blockchain));
electrumRequest.setError(App.Companion.getInstance().getString(R.string.cannot_obtain_data_from_blockchain));
electrumRequest.answerData=null;
}
} else {
electrumRequest.setError(App.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_no_answer));
electrumRequest.setError(App.Companion.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_no_answer));
Log.i(TAG, ">> <NULL>");
}
} catch (ConnectException e) {
e.printStackTrace();
electrumRequest.setError(App.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_no_connection));
electrumRequest.setError(App.Companion.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_no_connection));
Log.e(TAG, "doElectrumRequestSsl " + electrumRequest.getMethod() + " ConnectException " + e.getMessage());
} finally {
Log.i(TAG, "doElectrumRequestSsl " + electrumRequest.getMethod() + " socket.close");
@ -360,7 +360,7 @@ public class ServerApiElectrum {
}
catch (Exception e)
{
electrumRequest.setError(App.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_communication_error));
electrumRequest.setError(App.Companion.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_communication_error));
e.printStackTrace();
Log.e(TAG, "Can't close ssl socket");
}
@ -368,11 +368,11 @@ public class ServerApiElectrum {
} catch (IOException e) {
e.printStackTrace();
electrumRequest.setError(App.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_communication_error));
electrumRequest.setError(App.Companion.getInstance().getString(R.string.cannot_obtain_data_from_blockchain_communication_error));
Log.e(TAG, "doElectrumRequestSsl " + electrumRequest.getMethod() + " IOException " + e.getMessage());
}
} catch (NoSuchAlgorithmException | KeyManagementException e) {
electrumRequest.setError(App.getInstance().getString(R.string.cannot_obtain_data_from_blockchain));
electrumRequest.setError(App.Companion.getInstance().getString(R.string.cannot_obtain_data_from_blockchain));
Log.e(TAG, e.getMessage());
}
}

View file

@ -52,7 +52,7 @@ public class ServerApiInfura {
public void requestData(String method, int id, String wallet, String contract, String tx) {
requestsCount++;
InfuraApi infuraApi = App.getNetworkComponent().getRetrofitInfura().create(InfuraApi.class);
InfuraApi infuraApi = App.Companion.getNetworkComponent().getRetrofitInfura().create(InfuraApi.class);
InfuraBody infuraBody;
switch (method) {

View file

@ -52,7 +52,7 @@ public class ServerApiRootstock {
public void requestData(String method, int id, String wallet, String contract, String tx) {
requestsCount++;
RootstockApi rootstockApi = App.getNetworkComponent().getRetrofitRootstock().create(RootstockApi.class);
RootstockApi rootstockApi = App.Companion.getNetworkComponent().getRetrofitRootstock().create(RootstockApi.class);
InfuraBody infuraBody;
switch (method) {

View file

@ -1,39 +0,0 @@
package com.tangem.di;
import com.tangem.presentation.activity.EmptyWalletActivity;
import com.tangem.presentation.activity.LoadedWalletActivity;
import com.tangem.presentation.activity.LogoActivity;
import com.tangem.presentation.activity.MainActivity;
import com.tangem.presentation.activity.PrepareCryptonitOtherApiWithdrawalActivity;
import com.tangem.presentation.activity.PrepareKrakenWithdrawalActivity;
import com.tangem.presentation.activity.PrepareTransactionActivity;
import com.tangem.presentation.activity.PurgeActivity;
import com.tangem.presentation.activity.VerifyCardActivity;
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules = {NavigatorModule.class})
public interface NavigatorComponent {
void inject(LogoActivity activity);
void inject(MainActivity activity);
void inject(PurgeActivity activity);
void inject(PrepareTransactionActivity activity);
void inject(PrepareCryptonitOtherApiWithdrawalActivity activity);
void inject(PrepareKrakenWithdrawalActivity activity);
void inject(LoadedWalletActivity activity);
void inject(VerifyCardActivity activity);
void inject(EmptyWalletActivity activity);
}

View file

@ -0,0 +1,39 @@
package com.tangem.di
import com.tangem.presentation.activity.EmptyWalletActivity
import com.tangem.presentation.activity.LoadedWalletActivity
import com.tangem.presentation.activity.LogoActivity
import com.tangem.presentation.activity.MainActivity
import com.tangem.presentation.activity.PrepareCryptonitOtherApiWithdrawalActivity
import com.tangem.presentation.activity.PrepareKrakenWithdrawalActivity
import com.tangem.presentation.activity.PrepareTransactionActivity
import com.tangem.presentation.activity.PurgeActivity
import com.tangem.presentation.activity.VerifyCardActivity
import javax.inject.Singleton
import dagger.Component
@Singleton
@Component(modules = [NavigatorModule::class])
interface NavigatorComponent {
fun inject(activity: LogoActivity)
fun inject(activity: MainActivity)
fun inject(activity: PurgeActivity)
fun inject(activity: PrepareTransactionActivity)
fun inject(activity: PrepareCryptonitOtherApiWithdrawalActivity)
fun inject(activity: PrepareKrakenWithdrawalActivity)
fun inject(activity: LoadedWalletActivity)
fun inject(activity: VerifyCardActivity)
fun inject(activity: EmptyWalletActivity)
}

View file

@ -1,25 +0,0 @@
package com.tangem.di;
import com.tangem.presentation.dialog.WaitSecurityDelayDialogNew;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
class NavigatorModule {
@Singleton
@Provides
Navigator provideNavigator() {
return new Navigator();
}
@Singleton
@Provides
WaitSecurityDelayDialogNew provideWaitSecurityDelayDialogNew() {
return new WaitSecurityDelayDialogNew();
}
}

View file

@ -0,0 +1,25 @@
package com.tangem.di
import com.tangem.presentation.dialog.WaitSecurityDelayDialogNew
import javax.inject.Singleton
import dagger.Module
import dagger.Provides
@Module
internal class NavigatorModule {
@Singleton
@Provides
fun provideNavigator(): Navigator {
return Navigator()
}
@Singleton
@Provides
fun provideWaitSecurityDelayDialogNew(): WaitSecurityDelayDialogNew {
return WaitSecurityDelayDialogNew()
}
}

View file

@ -1,35 +0,0 @@
package com.tangem.di;
import com.tangem.data.network.Server;
import java.net.Socket;
import javax.inject.Named;
import javax.inject.Singleton;
import dagger.Component;
import retrofit2.Retrofit;
@Singleton
@Component(modules = {NetworkModule.class})
public interface NetworkComponent {
@Named(Server.ApiInfura.URL_INFURA)
Retrofit getRetrofitInfura();
@Named(Server.ApiEstimatefee.URL_ESTIMATEFEE)
Retrofit getRetrofitEstimatefee();
@Named(Server.ApiCoinmarket.URL_COINMARKET)
Retrofit getRetrofitCoinmarketcap();
@Named(Server.ApiUpdateVersion.URL_UPDATE_VERSION)
Retrofit getRetrofitGithubusercontent();
@Named(Server.ApiRootstock.URL_ROOTSTOCK)
Retrofit getRetrofitRootstock();
@Named("socket")
Socket getSocket();
}

View file

@ -0,0 +1,35 @@
package com.tangem.di
import com.tangem.data.network.Server
import java.net.Socket
import javax.inject.Named
import javax.inject.Singleton
import dagger.Component
import retrofit2.Retrofit
@Singleton
@Component(modules = [NetworkModule::class])
interface NetworkComponent {
@get:Named(Server.ApiInfura.URL_INFURA)
val retrofitInfura: Retrofit
@get:Named(Server.ApiEstimatefee.URL_ESTIMATEFEE)
val retrofitEstimatefee: Retrofit
@get:Named(Server.ApiCoinmarket.URL_COINMARKET)
val retrofitCoinmarketcap: Retrofit
@get:Named(Server.ApiUpdateVersion.URL_UPDATE_VERSION)
val retrofitGitHubUserContent: Retrofit
@get:Named(Server.ApiRootstock.URL_ROOTSTOCK)
val retrofitRootstock: Retrofit
@get:Named("socket")
val socket: Socket
}

View file

@ -1,106 +0,0 @@
package com.tangem.di;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import com.tangem.data.network.Server;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import javax.inject.Named;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
@Module
class NetworkModule {
@Singleton
@Provides
@Named(Server.ApiInfura.URL_INFURA)
Retrofit provideRetrofitInfura() {
return new Retrofit.Builder()
.baseUrl(Server.ApiInfura.URL_INFURA)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
@Singleton
@Provides
@Named(Server.ApiRootstock.URL_ROOTSTOCK)
Retrofit provideRetrofitRootstock() {
return new Retrofit.Builder()
.baseUrl(Server.ApiRootstock.URL_ROOTSTOCK)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
@Singleton
@Provides
@Named(Server.ApiEstimatefee.URL_ESTIMATEFEE)
Retrofit provideRetrofitEstimatefee() {
return new Retrofit.Builder()
.baseUrl(Server.ApiEstimatefee.URL_ESTIMATEFEE)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
@Singleton
@Provides
@Named(Server.ApiUpdateVersion.URL_UPDATE_VERSION)
Retrofit provideGithubusercontent() {
return new Retrofit.Builder()
.baseUrl(Server.ApiUpdateVersion.URL_UPDATE_VERSION)
.addConverterFactory(GsonConverterFactory.create())
.client(createOkHttpClient())
.build();
}
@Singleton
@Provides
@Named(Server.ApiCoinmarket.URL_COINMARKET)
Retrofit provideRetrofitCoinmarketcap() {
return new Retrofit.Builder()
.baseUrl(Server.ApiCoinmarket.URL_COINMARKET)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
private OkHttpClient createOkHttpClient() {
return new OkHttpClient.Builder().
addInterceptor(createHttpLoggingInterceptor()).
build();
}
private HttpLoggingInterceptor createHttpLoggingInterceptor() {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
return logging;
}
@Provides
@Named("socket")
Socket provideSocket() {
Socket socket = new Socket();
try {
socket.setSoTimeout(2000);
try {
socket.bind(new InetSocketAddress(0));
} catch (IOException e) {
e.printStackTrace();
}
} catch (SocketException e) {
e.printStackTrace();
}
return socket;
}
}

View file

@ -0,0 +1,105 @@
package com.tangem.di
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import com.tangem.data.network.Server
import java.io.IOException
import java.net.InetSocketAddress
import java.net.Socket
import java.net.SocketException
import javax.inject.Named
import javax.inject.Singleton
import dagger.Module
import dagger.Provides
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
@Module
internal class NetworkModule {
@Singleton
@Provides
@Named(Server.ApiInfura.URL_INFURA)
fun provideRetrofitInfura(): Retrofit {
return Retrofit.Builder()
.baseUrl(Server.ApiInfura.URL_INFURA)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
@Singleton
@Provides
@Named(Server.ApiRootstock.URL_ROOTSTOCK)
fun provideRetrofitRootstock(): Retrofit {
return Retrofit.Builder()
.baseUrl(Server.ApiRootstock.URL_ROOTSTOCK)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
@Singleton
@Provides
@Named(Server.ApiEstimatefee.URL_ESTIMATEFEE)
fun provideRetrofitEstimatefee(): Retrofit {
return Retrofit.Builder()
.baseUrl(Server.ApiEstimatefee.URL_ESTIMATEFEE)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
@Singleton
@Provides
@Named(Server.ApiUpdateVersion.URL_UPDATE_VERSION)
fun provideGithubusercontent(): Retrofit {
return Retrofit.Builder()
.baseUrl(Server.ApiUpdateVersion.URL_UPDATE_VERSION)
.addConverterFactory(GsonConverterFactory.create())
.client(createOkHttpClient())
.build()
}
@Singleton
@Provides
@Named(Server.ApiCoinmarket.URL_COINMARKET)
fun provideRetrofitCoinmarketcap(): Retrofit {
return Retrofit.Builder()
.baseUrl(Server.ApiCoinmarket.URL_COINMARKET)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
}
private fun createOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder().addInterceptor(createHttpLoggingInterceptor()).build()
}
private fun createHttpLoggingInterceptor(): HttpLoggingInterceptor {
val logging = HttpLoggingInterceptor()
logging.level = HttpLoggingInterceptor.Level.BODY
return logging
}
@Provides
@Named("socket")
fun provideSocket(): Socket {
val socket = Socket()
try {
socket.soTimeout = 2000
try {
socket.bind(InetSocketAddress(0))
} catch (e: IOException) {
e.printStackTrace()
}
} catch (e: SocketException) {
e.printStackTrace()
}
return socket
}
}

View file

@ -49,7 +49,7 @@ public class BalanceValidator {
}
}
public void Check(TangemContext ctx, Boolean attest) {
public void check(TangemContext ctx, Boolean attest) {
firstLine = "Verification failed";
secondLine = "";
TangemCard card = ctx.getCard();

View file

@ -247,10 +247,10 @@ public abstract class CoinEngine {
* Transaction processing sequence:
* 1. User enter transaction attributes
* 2. Application create instance of {@link SignTask.TransactionToSign} by call {@see constructTransaction}
* 3. Application set notification when transaction were prepared {@see setOnNeedSendTransaction} and start {@link SignTask}
* 3. Application set notification when transaction were prepared {@see setOnNeedSendTransaction} and init {@link SignTask}
* 4. User tap card and card sign transaction
* 5. Application receive {@link OnNeedSendTransaction} notification with prepared raw transaction
* 6. Application show user information that transaction ready for sending and start sending procedure by call {@see requestSendTransaction}
* 6. Application show user information that transaction ready for sending and init sending procedure by call {@see requestSendTransaction}
* 7. Application receive notification of sending result through {@link CoinEngine.BlockchainRequestsCallbacks} and show result to user
*
* @param amountValue - amount of desired transaction

View file

@ -4,6 +4,7 @@ import android.app.Activity
import android.content.Intent
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.os.Build
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.text.Editable
@ -13,11 +14,11 @@ import android.view.KeyEvent
import android.view.View
import android.widget.Toast
import com.tangem.Constant
import com.tangem.data.Blockchain
import com.tangem.domain.wallet.CoinEngine
import com.tangem.domain.wallet.CoinEngineFactory
import com.tangem.domain.wallet.TangemContext
import com.tangem.presentation.event.TransactionFinishWithError
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.tangemcard.data.TangemCard
import com.tangem.tangemcard.data.loadFromBundle
@ -44,12 +45,16 @@ class ConfirmTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallbac
setContentView(R.layout.activity_confirm_transaction)
nfcManager = NfcManager(this, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
ctx = TangemContext.loadFromBundle(this, intent.extras)
val engine = CoinEngineFactory.create(ctx)
val html = Html.fromHtml(engine!!.balanceHTML)
@Suppress("DEPRECATION") val html = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
Html.fromHtml(engine!!.balanceHTML, Html.FROM_HTML_MODE_LEGACY)
else
Html.fromHtml(engine!!.balanceHTML)
tvBalance.text = html
isIncludeFee = intent.getBooleanExtra(Constant.EXTRA_FEE_INCLUDED, true)
@ -74,7 +79,7 @@ class ConfirmTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallbac
btnSend.visibility = View.INVISIBLE
val allowFeeLevelSelection = engine!!.allowSelectFeeLevel()
val allowFeeLevelSelection = engine.allowSelectFeeLevel()
for (lol in rgFee.touchables) {
lol.isEnabled = allowFeeLevelSelection
}
@ -185,21 +190,6 @@ class ConfirmTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallbac
amount)
}
public override fun onResume() {
super.onResume()
nfcManager.onResume()
}
public override fun onPause() {
super.onPause()
nfcManager.onPause()
}
public override fun onStop() {
super.onStop()
nfcManager.onStop()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == Constant.REQUEST_CODE_SIGN_TRANSACTION) {

View file

@ -9,20 +9,16 @@ import android.nfc.NfcAdapter
import android.nfc.Tag
import android.nfc.tech.IsoDep
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.view.View
import android.view.animation.Animation
import android.view.animation.DecelerateInterpolator
import android.view.animation.Transformation
import android.widget.ProgressBar
import android.widget.RelativeLayout
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.tangem.App
import com.tangem.Constant
import com.tangem.domain.wallet.TangemContext
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
import com.tangem.tangemcard.android.nfc.DeviceNFCAntennaLocation
import com.tangem.tangemcard.android.nfc.NfcDeviceAntennaLocation
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.tangemcard.android.reader.NfcReader
import com.tangem.tangemcard.data.asBundle
@ -31,6 +27,7 @@ import com.tangem.tangemcard.tasks.CreateNewWalletTask
import com.tangem.tangemcard.util.Util
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_create_new_wallet.*
import kotlinx.android.synthetic.main.layout_progress_horizontal.*
import kotlinx.android.synthetic.main.layout_touch_card.*
class CreateNewWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications {
@ -46,51 +43,27 @@ class CreateNewWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
private lateinit var nfcManager: NfcManager
private lateinit var ctx: TangemContext
private lateinit var antenna: DeviceNFCAntennaLocation
private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation
private var createNewWalletTask: CreateNewWalletTask? = null
private var lastReadSuccess = true
private var progressBar: ProgressBar? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_create_new_wallet)
nfcManager = NfcManager(this, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
ctx = TangemContext.loadFromBundle(this, intent.extras)
// init NFC Antenna
nfcDeviceAntenna = NfcDeviceAntennaLocation(this, ivHandCardHorizontal, ivHandCardVertical, llHand, llNfc)
nfcDeviceAntenna.init()
tvCardId.text = ctx.card!!.cidDescription
progressBar = findViewById(R.id.progressBar)
progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
progressBar!!.visibility = View.INVISIBLE
// get NFC Antenna
antenna = DeviceNFCAntennaLocation()
antenna.getAntennaLocation()
// set card orientation
when (antenna.orientation) {
DeviceNFCAntennaLocation.CARD_ORIENTATION_HORIZONTAL -> {
ivHandCardHorizontal.visibility = View.VISIBLE
ivHandCardVertical.visibility = View.GONE
}
DeviceNFCAntennaLocation.CARD_ORIENTATION_VERTICAL -> {
ivHandCardVertical.visibility = View.VISIBLE
ivHandCardHorizontal.visibility = View.GONE
}
}
// set card z position
when (antenna.z) {
DeviceNFCAntennaLocation.CARD_ON_BACK -> llHand.elevation = 0.0f
DeviceNFCAntennaLocation.CARD_ON_FRONT -> llHand.elevation = 30.0f
}
animate()
progressBar.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
progressBar.visibility = View.INVISIBLE
}
override fun onTagDiscovered(tag: Tag) {
@ -120,32 +93,17 @@ class CreateNewWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
}
}
public override fun onResume() {
super.onResume()
nfcManager.onResume()
}
public override fun onPause() {
nfcManager.onPause()
if (createNewWalletTask != null)
createNewWalletTask!!.cancel(true)
createNewWalletTask?.cancel(true)
super.onPause()
}
public override fun onStop() {
// dismiss enable NFC dialog
nfcManager.onStop()
if (createNewWalletTask != null)
createNewWalletTask!!.cancel(true)
super.onStop()
}
override fun onReadStart(cardProtocol: CardProtocol) {
rlProgressBar.post { rlProgressBar.visibility = View.VISIBLE }
rlProgressBar?.post { rlProgressBar.visibility = View.VISIBLE }
progressBar!!.post {
progressBar!!.visibility = View.VISIBLE
progressBar!!.progress = 5
progressBar?.post {
progressBar?.visibility = View.VISIBLE
progressBar?.progress = 5
}
}
@ -210,11 +168,11 @@ class CreateNewWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
}
}, 500)
progressBar!!.postDelayed({
progressBar?.postDelayed({
try {
progressBar!!.progress = 0
progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
progressBar!!.visibility = View.INVISIBLE
progressBar?.progress = 0
progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
progressBar?.visibility = View.INVISIBLE
} catch (e: Exception) {
e.printStackTrace()
}
@ -222,17 +180,17 @@ class CreateNewWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
}
override fun onReadProgress(protocol: CardProtocol, progress: Int) {
progressBar!!.post { progressBar!!.progress = progress }
progressBar?.post { progressBar?.progress = progress }
}
override fun onReadCancel() {
createNewWalletTask = null
progressBar!!.postDelayed({
progressBar?.postDelayed({
try {
progressBar!!.progress = 0
progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
progressBar!!.visibility = View.INVISIBLE
progressBar?.progress = 0
progressBar?.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
progressBar?.visibility = View.INVISIBLE
} catch (e: Exception) {
e.printStackTrace()
}
@ -251,24 +209,4 @@ class CreateNewWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
WaitSecurityDelayDialog.onReadAfterRequest(this)
}
private fun animate() {
val lp = llHand.layoutParams as RelativeLayout.LayoutParams
val lp2 = llNfc.layoutParams as RelativeLayout.LayoutParams
val dp = resources.displayMetrics.density
val lm = dp * (69 + antenna.x * 75)
lp.topMargin = (dp * (-100 + antenna.y * 250)).toInt()
lp2.topMargin = (dp * (-125 + antenna.y * 250)).toInt()
llNfc.layoutParams = lp2
val a = object : Animation() {
override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
lp.leftMargin = (lm * interpolatedTime).toInt()
llHand.layoutParams = lp
}
}
a.duration = 2000
a.interpolator = DecelerateInterpolator()
llHand.startAnimation(a)
}
}

View file

@ -20,6 +20,7 @@ import com.tangem.di.Navigator
import com.tangem.domain.wallet.TangemContext
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.tangemcard.android.reader.NfcReader
import com.tangem.tangemcard.data.TangemCard
@ -61,9 +62,10 @@ class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_empty_wallet)
App.getNavigatorComponent().inject(this)
App.navigatorComponent?.inject(this)
nfcManager = NfcManager(this, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
ctx = TangemContext.loadFromBundle(this, intent.extras)
@ -99,21 +101,6 @@ class EmptyWalletActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Card
}
}
public override fun onResume() {
super.onResume()
nfcManager.onResume()
}
public override fun onPause() {
super.onPause()
nfcManager.onPause()
}
public override fun onStop() {
super.onStop()
nfcManager.onStop()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == Constant.REQUEST_CODE_CREATE_NEW_WALLET_ACTIVITY) {
if (resultCode == Activity.RESULT_OK) {

View file

@ -32,7 +32,7 @@ class LoadedWalletActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_loaded_wallet)
App.getNavigatorComponent().inject(this)
App.navigatorComponent?.inject(this)
if (intent.extras!!.containsKey(NfcAdapter.EXTRA_TAG)) {
val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)

View file

@ -31,7 +31,7 @@ class LogoActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_logo)
App.getNavigatorComponent().inject(this)
App.navigatorComponent?.inject(this)
ivLogo.setOnClickListener { hide() }
}

View file

@ -18,10 +18,6 @@ import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.animation.Animation
import android.view.animation.DecelerateInterpolator
import android.view.animation.Transformation
import android.widget.RelativeLayout
import android.widget.Toast
import com.scottyab.rootbeer.RootBeer
import com.tangem.App
@ -34,8 +30,8 @@ import com.tangem.domain.wallet.TangemContext
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
import com.tangem.presentation.dialog.RootFoundDialog
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
import com.tangem.presentation.dialog.WaitSecurityDelayDialogNew
import com.tangem.tangemcard.android.nfc.DeviceNFCAntennaLocation
import com.tangem.tangemcard.android.nfc.NfcDeviceAntennaLocation
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.tangemcard.android.reader.NfcReader
import com.tangem.tangemcard.data.TangemCard
@ -67,7 +63,7 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
private lateinit var nfcManager: NfcManager
private var zipFile: File? = null
private lateinit var antenna: DeviceNFCAntennaLocation
private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation
private var unsuccessReadCount = 0
private var lastTag: Tag? = null
private var readCardInfoTask: ReadCardInfoTask? = null
@ -86,11 +82,12 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
App.getNavigatorComponent().inject(this)
App.navigatorComponent?.inject(this)
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
nfcManager = NfcManager(this, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
verifyPermissions()
@ -100,34 +97,13 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
rippleBackgroundNfc.startRippleAnimation()
// get NFC Antenna
antenna = DeviceNFCAntennaLocation()
antenna.getAntennaLocation()
// set card orientation
when (antenna.orientation) {
DeviceNFCAntennaLocation.CARD_ORIENTATION_HORIZONTAL -> {
ivHandCardHorizontal.visibility = View.VISIBLE
ivHandCardVertical.visibility = View.GONE
}
DeviceNFCAntennaLocation.CARD_ORIENTATION_VERTICAL -> {
ivHandCardVertical.visibility = View.VISIBLE
ivHandCardHorizontal.visibility = View.GONE
}
}
// set card z position
when (antenna.z) {
DeviceNFCAntennaLocation.CARD_ON_BACK -> llHand.elevation = 0.0f
DeviceNFCAntennaLocation.CARD_ON_FRONT -> llHand.elevation = 30.0f
}
animate()
// init NFC Antenna
nfcDeviceAntenna = NfcDeviceAntennaLocation(this, ivHandCardHorizontal, ivHandCardVertical, llHand, llNfc)
nfcDeviceAntenna.init()
// set phone name
if (antenna.fullName != "")
tvNFCHint.text = String.format(getString(R.string.scan_banknote), antenna.fullName)
if (nfcDeviceAntenna.fullName != "")
tvNFCHint.text = String.format(getString(R.string.scan_banknote), nfcDeviceAntenna.fullName)
else
tvNFCHint.text = String.format(getString(R.string.scan_banknote), getString(R.string.phone))
@ -267,20 +243,16 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
public override fun onResume() {
super.onResume()
animate()
nfcDeviceAntenna.animate()
ReadCardInfoTask.resetLastReadInfo()
nfcManager.onResume()
}
public override fun onPause() {
nfcManager.onPause()
readCardInfoTask?.cancel(true)
super.onPause()
}
public override fun onStop() {
// dismiss enable NFC dialog
nfcManager.onStop()
readCardInfoTask?.cancel(true)
super.onStop()
}
@ -385,26 +357,6 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
onNfcReaderCallback = callback
}
private fun animate() {
val lp = llHand.layoutParams as RelativeLayout.LayoutParams
val lp2 = llNfc.layoutParams as RelativeLayout.LayoutParams
val dp = resources.displayMetrics.density
val lm = dp * (69 + antenna.x * 75)
lp.topMargin = (dp * (-100 + antenna.y * 250)).toInt()
lp2.topMargin = (dp * (-125 + antenna.y * 250)).toInt()
llNfc.layoutParams = lp2
val a = object : Animation() {
override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
lp.leftMargin = (lm * interpolatedTime).toInt()
llHand.layoutParams = lp
}
}
a.duration = 2000
a.interpolator = DecelerateInterpolator()
llHand.startAnimation(a)
}
private fun showMenu(v: View) {
val popup = PopupMenu(this, v)
val inflater = popup.menuInflater

View file

@ -25,6 +25,7 @@ import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.data.fingerprint.FingerprintHelper
import com.tangem.domain.wallet.TangemContext
import com.tangem.tangemcard.android.data.PINStorage
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.tangemcard.data.TangemCard
import com.tangem.tangemcard.data.loadFromBundle
import com.tangem.tangemcard.data.EXTRA_TANGEM_CARD
@ -100,6 +101,7 @@ class PinRequestActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Finge
setContentView(R.layout.activity_pin_request)
nfcManager = NfcManager(this, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
mode = Mode.valueOf(intent.getStringExtra(Constant.EXTRA_MODE))
@ -171,34 +173,26 @@ class PinRequestActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Finge
override fun onPause() {
super.onPause()
if (fingerprintHelper != null)
fingerprintHelper!!.cancel()
fingerprintHelper?.cancel()
if (startFingerprintReaderTask != null) {
startFingerprintReaderTask!!.cancel(true)
startFingerprintReaderTask = null
}
nfcManager.onPause()
}
override fun onStop() {
super.onStop()
if (fingerprintHelper != null)
fingerprintHelper!!.cancel()
fingerprintHelper?.cancel()
if (startFingerprintReaderTask != null) {
startFingerprintReaderTask!!.cancel(true)
startFingerprintReaderTask = null
}
nfcManager.onStop()
}
override fun onResume() {
super.onResume()
nfcManager.onResume()
if (allowFingerprint)
startFingerprintReader()
}
@ -218,7 +212,7 @@ class PinRequestActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Finge
@TargetApi(Build.VERSION_CODES.M)
override fun authenticationSucceeded(result: FingerprintManager.AuthenticationResult) {
LOG.i(TAG,"Authentication succeeded!")
LOG.i(TAG, "Authentication succeeded!")
val cipher = result.cryptoObject.cipher
if (mode == Mode.RequestNewPIN || mode == Mode.ConfirmNewPIN) {
@ -246,34 +240,33 @@ class PinRequestActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Finge
finish()
}
@SuppressLint("SetTextI18n")
private fun buttonClick(button: Button) {
tvPin!!.text = tvPin!!.text.toString() + button.text as String
tvPin.text = tvPin.text.toString() + button.text.toString()
}
@SuppressLint("NewApi")
private fun testFingerPrintSettings(): Boolean {
LOG.i(TAG,"Testing Fingerprint Settings")
LOG.i(TAG, "Testing Fingerprint Settings")
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
fingerprintManager = getSystemService(Context.FINGERPRINT_SERVICE) as FingerprintManager
if (!keyguardManager.isKeyguardSecure) {
LOG.i(TAG,"User hasn't enabled Lock Screen")
LOG.i(TAG, "User hasn't enabled Lock Screen")
return false
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
LOG.i(TAG,"User hasn't granted permission to use Fingerprint")
LOG.i(TAG, "User hasn't granted permission to use Fingerprint")
return false
}
if (!fingerprintManager!!.hasEnrolledFingerprints()) {
LOG.i(TAG,"User hasn't registered any fingerprints")
LOG.i(TAG, "User hasn't registered any fingerprints")
return false
}
LOG.i(TAG,"Fingerprint authentication is set.\n")
LOG.i(TAG, "Fingerprint authentication is set.\n")
return true
}

View file

@ -17,6 +17,7 @@ import com.tangem.App
import com.tangem.Constant
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.tangemcard.android.reader.NfcReader
import com.tangem.tangemcard.data.*
@ -56,6 +57,7 @@ class PinSwapActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProt
setContentView(R.layout.activity_pin_swap)
nfcManager = NfcManager(this, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
card = TangemCard(intent.getStringExtra(EXTRA_TANGEM_CARD_UID))
card!!.loadFromBundle(intent.extras!!.getBundle(EXTRA_TANGEM_CARD))
@ -92,23 +94,13 @@ class PinSwapActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProt
}
}
public override fun onResume() {
super.onResume()
nfcManager.onResume()
}
public override fun onPause() {
nfcManager.onPause()
if (swapPinTask != null)
swapPinTask!!.cancel(true)
swapPinTask?.cancel(true)
super.onPause()
}
public override fun onStop() {
// dismiss enable NFC dialog
nfcManager.onStop()
if (swapPinTask != null)
swapPinTask!!.cancel(true)
swapPinTask?.cancel(true)
super.onStop()
}

View file

@ -16,6 +16,7 @@ import com.tangem.data.network.CryptonitOtherApi
import com.tangem.di.Navigator
import com.tangem.domain.wallet.CoinEngineFactory
import com.tangem.domain.wallet.TangemContext
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_prepare_cryptonit_other_api_withdrawal.*
@ -41,9 +42,10 @@ class PrepareCryptonitOtherApiWithdrawalActivity : AppCompatActivity(), NfcAdapt
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_prepare_cryptonit_other_api_withdrawal)
App.getNavigatorComponent().inject(this)
App.navigatorComponent?.inject(this)
nfcManager = NfcManager(this, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
ctx = TangemContext.loadFromBundle(this, intent.extras)
@ -129,47 +131,6 @@ class PrepareCryptonitOtherApiWithdrawalActivity : AppCompatActivity(), NfcAdapt
doRequestBalance()
}
private fun doRequestBalance() {
if (cryptonit!!.havaAccountInfo()) {
rlProgressBar.visibility = View.VISIBLE
tvProgressDescription.text = getString(R.string.cryptonit_request_balance)
tvError.visibility = View.INVISIBLE
cryptonit!!.requestBalance(ctx.blockchain.currency, "USD")
} else {
tvError.visibility = View.VISIBLE
tvError.text = getString(R.string.cryptonit_not_enough_account_data)
}
}
// private fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
// this.addTextChangedListener(object : TextWatcher {
// override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
// }
//
// override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
// }
//
// override fun afterTextChanged(editable: Editable?) {
// afterTextChanged.invoke(editable.toString())
// }
// })
// }
public override fun onResume() {
super.onResume()
nfcManager.onResume()
}
public override fun onPause() {
super.onPause()
nfcManager.onPause()
}
public override fun onStop() {
super.onStop()
nfcManager.onStop()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && data != null && data.extras!!.containsKey("QRCode")) {
@ -198,7 +159,18 @@ class PrepareCryptonitOtherApiWithdrawalActivity : AppCompatActivity(), NfcAdapt
} catch (e: IOException) {
e.printStackTrace()
}
}
private fun doRequestBalance() {
if (cryptonit!!.havaAccountInfo()) {
rlProgressBar.visibility = View.VISIBLE
tvProgressDescription.text = getString(R.string.cryptonit_request_balance)
tvError.visibility = View.INVISIBLE
cryptonit!!.requestBalance(ctx.blockchain.currency, "USD")
} else {
tvError.visibility = View.VISIBLE
tvError.text = getString(R.string.cryptonit_not_enough_account_data)
}
}
}

View file

@ -17,6 +17,7 @@ import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.data.Blockchain
import com.tangem.domain.wallet.CoinEngineFactory
import com.tangem.domain.wallet.TangemContext
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.util.DecimalDigitsInputFilter
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_prepare_cryptonit_withdrawal.*
@ -28,8 +29,8 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
val TAG: String = PrepareCryptonitWithdrawalActivity::class.java.simpleName
}
private lateinit var nfcManager: NfcManager
private lateinit var ctx: TangemContext
private lateinit var nfcManager: NfcManager
private var cryptonit: Cryptonit? = null
@ -38,10 +39,11 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_prepare_cryptonit_withdrawal)
nfcManager = NfcManager(this, this)
ctx = TangemContext.loadFromBundle(this, intent.extras)
nfcManager = NfcManager(this, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
cryptonit = Cryptonit(this)
etUsername.setText(cryptonit!!.username)
@ -56,17 +58,17 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
tvFeeCurrency.text = engine.feeCurrency
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toValueString())
etAmount.filters=engine.amountInputFilters
etAmount.filters = engine.amountInputFilters
etAmount.setOnEditorActionListener { lv, actionId, event ->
etAmount.setOnEditorActionListener { lv, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
val imm = lv.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(lv.windowToken, 0)
true
} else {
} else
false
}
}
when (ctx.blockchain) {
Blockchain.Bitcoin -> {
etAmount.filters = arrayOf<InputFilter>(DecimalDigitsInputFilter(5))
@ -125,7 +127,7 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
cryptonit!!.setWithdrawalListener { response ->
rlProgressBar.visibility = View.INVISIBLE
if (response.success != null && response.success!!) {
Toast.makeText(this, "Withdrawal successful!", Toast.LENGTH_LONG).show();
Toast.makeText(this, R.string.withdrawal_successful, Toast.LENGTH_LONG).show();
finish()
} else {
tvError.visibility = View.VISIBLE
@ -136,6 +138,14 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
doRequestBalance()
}
override fun onTagDiscovered(tag: Tag) {
try {
nfcManager.ignoreTag(tag)
} catch (e: IOException) {
e.printStackTrace()
}
}
private fun doRequestBalance() {
if (cryptonit!!.haveAccountInfo()) {
rlProgressBar.visibility = View.VISIBLE
@ -148,28 +158,4 @@ class PrepareCryptonitWithdrawalActivity : AppCompatActivity(), NfcAdapter.Reade
}
}
public override fun onResume() {
super.onResume()
nfcManager.onResume()
}
public override fun onPause() {
super.onPause()
nfcManager.onPause()
}
public override fun onStop() {
super.onStop()
nfcManager.onStop()
}
override fun onTagDiscovered(tag: Tag) {
try {
nfcManager.ignoreTag(tag)
} catch (e: IOException) {
e.printStackTrace()
}
}
}

View file

@ -23,6 +23,7 @@ import com.tangem.data.Blockchain
import com.tangem.di.Navigator
import com.tangem.domain.wallet.CoinEngineFactory
import com.tangem.domain.wallet.TangemContext
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_prepare_kraken_withdrawal.*
import java.io.IOException
@ -38,7 +39,8 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
}
private lateinit var ctx: TangemContext
private var nfcManager: NfcManager? = null
private lateinit var nfcManager: NfcManager
private var kraken: Kraken? = null
private var fee: BigDecimal? = null
@ -50,12 +52,13 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_prepare_kraken_withdrawal)
App.getNavigatorComponent().inject(this)
nfcManager = NfcManager(this, this)
App.navigatorComponent?.inject(this)
ctx = TangemContext.loadFromBundle(this, intent.extras)
nfcManager = NfcManager(this, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
kraken = Kraken(this)
tvKey.text = kraken!!.key
@ -68,7 +71,7 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
tvCurrency.text = engine!!.balanceCurrency
etAmount.setText(engine.convertToAmount(engine.convertToInternalAmount(ctx.card!!.denomination)).toValueString())
etAmount.filters=engine.amountInputFilters
etAmount.filters = engine.amountInputFilters
etAmount.setOnEditorActionListener { lv, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
@ -167,7 +170,7 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
val builder = AlertDialog.Builder(this)
// Set a title for alert dialog
builder.setTitle("Please confirm withdraw")
builder.setTitle(R.string.please_confirm_withdraw)
// Set a message for alert dialog
builder.setMessage(String.format("Continue with fee %s %s?", fee!!.toString().trimEnd('0'), ctx.blockchain.currency))
@ -186,23 +189,22 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
rlProgressBar.visibility = View.VISIBLE
tvProgressDescription.text = getString(R.string.kraken_request_withdrawal)
//Toast.makeText(this, String.format("Withdraw %s!",dblAmount.toString()), Toast.LENGTH_LONG).show()
kraken!!.requestWithdraw(ctx.blockchain.currency, dblAmount.toString(), ctx.coinData!!.wallet)
} catch (e: Exception) {
etAmount.error = getString(R.string.unknown_amount_format)
}
}
DialogInterface.BUTTON_NEGATIVE -> {
Toast.makeText(this, "Operation canceled!", Toast.LENGTH_LONG).show()
Toast.makeText(this, R.string.operation_canceled, Toast.LENGTH_LONG).show()
}
}
}
// Set the alert dialog positive/yes button
builder.setPositiveButton("YES", dialogClickListener)
builder.setPositiveButton(R.string.yes, dialogClickListener)
// Set the alert dialog negative/no button
builder.setNegativeButton("NO", dialogClickListener)
builder.setNegativeButton(R.string.no, dialogClickListener)
// Initialize the AlertDialog using builder object
@ -224,21 +226,6 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
}
}
public override fun onResume() {
super.onResume()
nfcManager!!.onResume()
}
public override fun onPause() {
super.onPause()
nfcManager!!.onPause()
}
public override fun onStop() {
super.onStop()
nfcManager!!.onStop()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && data != null && data.extras!!.containsKey("QRCode")) {
@ -262,12 +249,10 @@ class PrepareKrakenWithdrawalActivity : AppCompatActivity(), NfcAdapter.ReaderCa
override fun onTagDiscovered(tag: Tag) {
try {
// Log.w(javaClass.name, "Ignore discovered tag!")
nfcManager!!.ignoreTag(tag)
nfcManager.ignoreTag(tag)
} catch (e: IOException) {
e.printStackTrace()
}
}
}

View file

@ -11,6 +11,7 @@ import android.text.Html
import android.view.View
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.tangem.App
import com.tangem.Constant
@ -18,7 +19,9 @@ import com.tangem.data.Blockchain
import com.tangem.di.Navigator
import com.tangem.domain.wallet.CoinEngineFactory
import com.tangem.domain.wallet.TangemContext
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.util.UtilHelper
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_prepare_transaction.*
import java.io.IOException
@ -44,9 +47,10 @@ class PrepareTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallbac
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_prepare_transaction)
App.getNavigatorComponent().inject(this)
App.navigatorComponent?.inject(this)
nfcManager = NfcManager(this, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
ctx = TangemContext.loadFromBundle(this, intent.extras)
@ -87,8 +91,12 @@ class PrepareTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallbac
}
btnVerify.setOnClickListener {
val engine1 = CoinEngineFactory.create(ctx)
if (!UtilHelper.isOnline(this)) {
Toast.makeText(this, R.string.no_connection, Toast.LENGTH_LONG).show()
return@setOnClickListener
}
val engine1 = CoinEngineFactory.create(ctx)
val strAmount: String = etAmount.text.toString().replace(",", ".")
val amount = engine1!!.convertToAmount(etAmount.text.toString(), tvCurrency.text.toString())
@ -129,21 +137,6 @@ class PrepareTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallbac
ivCamera.setOnClickListener { navigator.showQrScanActivity(this, Constant.REQUEST_CODE_SCAN_QR) }
}
public override fun onResume() {
super.onResume()
nfcManager.onResume()
}
public override fun onPause() {
super.onPause()
nfcManager.onPause()
}
public override fun onStop() {
super.onStop()
nfcManager.onStop()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == Constant.REQUEST_CODE_SCAN_QR && resultCode == Activity.RESULT_OK && data != null && data.extras!!.containsKey("QRCode")) {

View file

@ -10,28 +10,22 @@ import android.nfc.NfcAdapter
import android.nfc.Tag
import android.nfc.tech.IsoDep
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.view.View
import android.view.animation.Animation
import android.view.animation.DecelerateInterpolator
import android.view.animation.Transformation
import android.widget.RelativeLayout
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.tangem.App
import com.tangem.tangemcard.tasks.PurgeTask
import com.tangem.tangemcard.reader.CardProtocol
import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.domain.wallet.TangemContext
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
import com.tangem.presentation.dialog.WaitSecurityDelayDialogNew
import com.tangem.presentation.event.DeletingWalletFinish
import com.tangem.presentation.event.ReadAfterRequest
import com.tangem.presentation.event.ReadBeforeRequest
import com.tangem.presentation.event.ReadWait
import com.tangem.tangemcard.android.nfc.DeviceNFCAntennaLocation
import com.tangem.tangemcard.android.nfc.NfcDeviceAntennaLocation
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.tangemcard.android.reader.NfcReader
import com.tangem.tangemcard.data.asBundle
import com.tangem.tangemcard.reader.CardProtocol
import com.tangem.tangemcard.tasks.PurgeTask
import com.tangem.tangemcard.util.Util
import com.tangem.util.LOG
import com.tangem.wallet.R
@ -59,7 +53,7 @@ class PurgeActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoc
private lateinit var nfcManager: NfcManager
private lateinit var ctx: TangemContext
private lateinit var antenna: DeviceNFCAntennaLocation
private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation
private var purgeTask: PurgeTask? = null
@ -67,58 +61,25 @@ class PurgeActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoc
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_purge)
App.getNavigatorComponent().inject(this)
App.navigatorComponent?.inject(this)
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
nfcManager = NfcManager(this, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
ctx = TangemContext.loadFromBundle(this, intent.extras)
// init NFC Antenna
nfcDeviceAntenna = NfcDeviceAntennaLocation(this, ivHandCardHorizontal, ivHandCardVertical, llHand, llNfc)
nfcDeviceAntenna.init()
tvCardID.text = ctx.card!!.cidDescription
progressBar.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
progressBar.visibility = View.INVISIBLE
// get NFC Antenna
antenna = DeviceNFCAntennaLocation()
antenna.getAntennaLocation()
// set card orientation
when (antenna.orientation) {
DeviceNFCAntennaLocation.CARD_ORIENTATION_HORIZONTAL -> {
ivHandCardHorizontal.visibility = View.VISIBLE
ivHandCardVertical.visibility = View.GONE
}
DeviceNFCAntennaLocation.CARD_ORIENTATION_VERTICAL -> {
ivHandCardVertical.visibility = View.VISIBLE
ivHandCardHorizontal.visibility = View.GONE
}
}
// set card z position
when (antenna.z) {
DeviceNFCAntennaLocation.CARD_ON_BACK -> llHand.elevation = 0.0f
DeviceNFCAntennaLocation.CARD_ON_FRONT -> llHand.elevation = 30.0f
}
animate()
}
public override fun onResume() {
super.onResume()
nfcManager.onResume()
}
public override fun onPause() {
nfcManager.onPause()
purgeTask?.cancel(true)
super.onPause()
}
public override fun onStop() {
// dismiss enable NFC dialog
nfcManager.onStop()
purgeTask?.cancel(true)
super.onStop()
}
@ -126,7 +87,8 @@ class PurgeActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoc
override fun onTagDiscovered(tag: Tag) {
try {
// get IsoDep handle and run cardReader thread
val isoDep = IsoDep.get(tag) ?: throw CardProtocol.TangemException(getString(R.string.wrong_tag_err))
val isoDep = IsoDep.get(tag)
?: throw CardProtocol.TangemException(getString(R.string.wrong_tag_err))
val uid = tag.id
val sUID = Util.byteArrayToHexString(uid)
LOG.d(TAG, "UID: $sUID")
@ -274,24 +236,4 @@ class PurgeActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoc
}, 500)
}
private fun animate() {
val lp = llHand.layoutParams as RelativeLayout.LayoutParams
val lp2 = llNfc.layoutParams as RelativeLayout.LayoutParams
val dp = resources.displayMetrics.density
val lm = dp * (69 + antenna.x * 75)
lp.topMargin = (dp * (-100 + antenna.y * 250)).toInt()
lp2.topMargin = (dp * (-125 + antenna.y * 250)).toInt()
llNfc.layoutParams = lp2
val a = object : Animation() {
override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
lp.leftMargin = (lm * interpolatedTime).toInt()
llHand.layoutParams = lp
}
}
a.duration = 2000
a.interpolator = DecelerateInterpolator()
llHand.startAnimation(a)
}
}

View file

@ -13,6 +13,7 @@ import com.tangem.domain.wallet.CoinEngineFactory
import com.tangem.domain.wallet.TangemContext
import com.tangem.presentation.event.TransactionFinishWithError
import com.tangem.presentation.event.TransactionFinishWithSuccess
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.util.UtilHelper
import com.tangem.wallet.R
@ -31,6 +32,7 @@ class SendTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
setContentView(R.layout.activity_send_transaction)
nfcManager = NfcManager(this, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
ctx = TangemContext.loadFromBundle(this, intent.extras)
tx = intent.getByteArrayExtra(Constant.EXTRA_TX)
@ -67,21 +69,6 @@ class SendTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
return super.onKeyDown(keyCode, event)
}
public override fun onResume() {
super.onResume()
nfcManager.onResume()
}
public override fun onPause() {
super.onPause()
nfcManager.onPause()
}
public override fun onStop() {
super.onStop()
nfcManager.onStop()
}
override fun onTagDiscovered(tag: Tag) {
try {
nfcManager.ignoreTag(tag)

View file

@ -8,15 +8,10 @@ import android.nfc.NfcAdapter
import android.nfc.Tag
import android.nfc.tech.IsoDep
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.view.KeyEvent
import android.view.View
import android.view.animation.Animation
import android.view.animation.DecelerateInterpolator
import android.view.animation.Transformation
import android.widget.ProgressBar
import android.widget.RelativeLayout
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.tangem.App
import com.tangem.Constant
import com.tangem.domain.wallet.CoinEngine
@ -24,7 +19,8 @@ import com.tangem.domain.wallet.CoinEngineFactory
import com.tangem.domain.wallet.TangemContext
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
import com.tangem.tangemcard.android.nfc.DeviceNFCAntennaLocation
import com.tangem.tangemcard.android.nfc.NfcDeviceAntennaLocation
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.tangemcard.android.reader.NfcReader
import com.tangem.tangemcard.data.asBundle
@ -34,6 +30,7 @@ import com.tangem.tangemcard.util.Util
import com.tangem.util.LOG
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_sign_transaction.*
import kotlinx.android.synthetic.main.layout_progress_horizontal.*
import kotlinx.android.synthetic.main.layout_touch_card.*
class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications {
@ -45,7 +42,7 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
private lateinit var nfcManager: NfcManager
private lateinit var ctx: TangemContext
private lateinit var antenna: DeviceNFCAntennaLocation
private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation
private var signTransactionTask: SignTask? = null
@ -55,70 +52,36 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
private var outAddressStr: String? = null
private var lastReadSuccess = true
private var progressBar: ProgressBar? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sign_transaction)
nfcManager = NfcManager(this, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
ctx = TangemContext.loadFromBundle(this, intent.extras)
// init NFC Antenna
nfcDeviceAntenna = NfcDeviceAntennaLocation(this, ivHandCardHorizontal, ivHandCardVertical, llHand, llNfc)
nfcDeviceAntenna.init()
amount = CoinEngine.Amount(intent.getStringExtra(Constant.EXTRA_AMOUNT), intent.getStringExtra(Constant.EXTRA_AMOUNT_CURRENCY))
fee = CoinEngine.Amount(intent.getStringExtra(Constant.EXTRA_FEE), intent.getStringExtra(Constant.EXTRA_FEE_CURRENCY))
isIncludeFee = intent.getBooleanExtra(Constant.EXTRA_FEE_INCLUDED, true)
outAddressStr = intent.getStringExtra(Constant.EXTRA_TARGET_ADDRESS)
tvCardID.text = ctx.card!!.cidDescription
progressBar = findViewById(R.id.progressBar)
progressBar!!.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
progressBar!!.visibility = View.INVISIBLE
// get NFC Antenna
antenna = DeviceNFCAntennaLocation()
antenna.getAntennaLocation()
// set card orientation
when (antenna.orientation) {
DeviceNFCAntennaLocation.CARD_ORIENTATION_HORIZONTAL -> {
ivHandCardHorizontal.visibility = View.VISIBLE
ivHandCardVertical.visibility = View.GONE
}
DeviceNFCAntennaLocation.CARD_ORIENTATION_VERTICAL -> {
ivHandCardVertical.visibility = View.VISIBLE
ivHandCardHorizontal.visibility = View.GONE
}
}
// set card z position
when (antenna.z) {
DeviceNFCAntennaLocation.CARD_ON_BACK -> llHand.elevation = 0.0f
DeviceNFCAntennaLocation.CARD_ON_FRONT -> llHand.elevation = 30.0f
}
animate()
}
public override fun onResume() {
super.onResume()
nfcManager.onResume()
progressBar.progressTintList = ColorStateList.valueOf(Color.DKGRAY)
progressBar.visibility = View.INVISIBLE
}
public override fun onPause() {
nfcManager.onPause()
if (signTransactionTask != null)
signTransactionTask!!.cancel(true)
signTransactionTask?.cancel(true)
super.onPause()
}
public override fun onStop() {
// dismiss enable NFC dialog
nfcManager.onStop()
if (signTransactionTask != null)
signTransactionTask!!.cancel(true)
signTransactionTask?.cancel(true)
super.onStop()
}
@ -194,14 +157,14 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
override fun onReadStart(cardProtocol: CardProtocol) {
rlProgressBar.post { rlProgressBar.visibility = View.VISIBLE }
progressBar!!.post {
progressBar!!.visibility = View.VISIBLE
progressBar!!.progress = 5
progressBar?.post {
progressBar?.visibility = View.VISIBLE
progressBar?.progress = 5
}
}
override fun onReadProgress(protocol: CardProtocol, progress: Int) {
progressBar!!.post { progressBar!!.progress = progress }
progressBar?.post { progressBar!!.progress = progress }
}
override fun onReadFinish(cardProtocol: CardProtocol?) {
@ -311,7 +274,6 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
// val readBeforeRequest = ReadBeforeRequest()
// readBeforeRequest.timeout = timeout
// EventBus.getDefault().post(readBeforeRequest)
}
override fun onReadAfterRequest() {
@ -320,7 +282,6 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
// val readAfterRequest = ReadAfterRequest()
// EventBus.getDefault().post(readAfterRequest)
}
override fun onReadWait(msec: Int) {
@ -330,29 +291,6 @@ class SignTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback,
// val readWait = ReadWait()
// readWait.msec = msec
// EventBus.getDefault().post(readWait)
}
private fun animate() {
val lp = llHand.layoutParams as RelativeLayout.LayoutParams
val lp2 = llNfc.layoutParams as RelativeLayout.LayoutParams
val dp = resources.displayMetrics.density
val lm = dp * (69 + antenna.x * 75)
lp.topMargin = (dp * (-100 + antenna.y * 250)).toInt()
lp2.topMargin = (dp * (-125 + antenna.y * 250)).toInt()
llNfc.layoutParams = lp2
val a = object : Animation() {
override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
lp.leftMargin = (lm * interpolatedTime).toInt()
llHand.layoutParams = lp
}
}
a.duration = 2000
a.interpolator = DecelerateInterpolator()
llHand.startAnimation(a)
}
}

View file

@ -29,7 +29,7 @@ class VerifyCardActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_verify_card)
App.getNavigatorComponent().inject(this)
App.navigatorComponent?.inject(this)
}
override fun onBackPressed() {

View file

@ -4,6 +4,8 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
import com.tangem.wallet.R;
@ -29,9 +31,9 @@ public class PINSwapWarningDialog extends DialogFragment {
message = getArguments().getString(EXTRA_MESSAGE);
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.tangem_logo_small_new)
.setTitle(R.string.your_money_is_at_risk)

View file

@ -1,6 +1,5 @@
package com.tangem.presentation.dialog;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;

View file

@ -3,8 +3,6 @@ package com.tangem.presentation.dialog;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;

View file

@ -27,10 +27,7 @@ import com.tangem.domain.wallet.BalanceValidator
import com.tangem.domain.wallet.CoinEngine
import com.tangem.domain.wallet.CoinEngineFactory
import com.tangem.domain.wallet.TangemContext
import com.tangem.presentation.activity.LoadedWalletActivity
import com.tangem.presentation.activity.PinRequestActivity
import com.tangem.presentation.activity.PrepareCryptonitWithdrawalActivity
import com.tangem.presentation.activity.PrepareKrakenWithdrawalActivity
import com.tangem.presentation.activity.*
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
import com.tangem.presentation.dialog.PINSwapWarningDialog
import com.tangem.presentation.dialog.ShowQRCodeDialog
@ -38,6 +35,7 @@ import com.tangem.presentation.dialog.WaitSecurityDelayDialog
import com.tangem.presentation.event.DeletingWalletFinish
import com.tangem.presentation.event.TransactionFinishWithError
import com.tangem.presentation.event.TransactionFinishWithSuccess
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.tangemcard.android.reader.NfcReader
import com.tangem.tangemcard.data.EXTRA_TANGEM_CARD
@ -66,14 +64,10 @@ class LoadedWallet : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback
val TAG: String = LoadedWallet::class.java.simpleName
}
private lateinit var ctx: TangemContext
private lateinit var nfcManager: NfcManager
private var serverApiCommon: ServerApiCommon = ServerApiCommon()
private var serverApiTangem: ServerApiTangem = ServerApiTangem()
private lateinit var ctx: TangemContext
private var lastTag: Tag? = null
private var lastReadSuccess = true
private var verifyCardTask: VerifyCardTask? = null
@ -82,25 +76,39 @@ class LoadedWallet : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback
private var newPIN = ""
private var newPIN2 = ""
private var cardProtocol: CardProtocol? = null
private val inactiveColor: ColorStateList by lazy { resources.getColorStateList(R.color.btn_dark) }
private val activeColor: ColorStateList by lazy { resources.getColorStateList(R.color.colorAccent) }
private val inactiveColor: ColorStateList by lazy {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
resources.getColorStateList(R.color.btn_dark, activity?.theme)
else
@Suppress("DEPRECATION")
resources.getColorStateList(R.color.btn_dark)
}
private val activeColor: ColorStateList by lazy {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
resources.getColorStateList(R.color.colorAccent, activity?.theme)
else
@Suppress("DEPRECATION")
resources.getColorStateList(R.color.colorAccent)
}
private var requestCounter: Int = 0
set(value) {
field = value
LOG.i(TAG, "requestCounter, set $field")
if (field <= 0) {
LOG.e(TAG, "+++++++++++ FINISH REFRESH")
if (srl != null && srl.isRefreshing) srl.isRefreshing = false
//updateViews()
} else if (srl != null && !srl.isRefreshing) srl.isRefreshing = true
if (srl != null && srl.isRefreshing)
srl.isRefreshing = false
} else if (srl != null && !srl.isRefreshing)
srl.isRefreshing = true
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
nfcManager = NfcManager(activity, this)
ctx = TangemContext.loadFromBundle(activity, activity?.intent?.extras)
nfcManager = NfcManager(activity!!, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
lastTag = activity?.intent?.getParcelableExtra(Constant.EXTRA_LAST_DISCOVERED_TAG)
}
@ -111,7 +119,7 @@ class LoadedWallet : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val engine=CoinEngineFactory.create(ctx)
val engine = CoinEngineFactory.create(ctx)
tvBalance.setSingleLine(!engine!!.needMultipleLinesForBalance())
@ -142,7 +150,7 @@ class LoadedWallet : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback
getString(R.string.in_app) -> {
try {
val engine = CoinEngineFactory.create(ctx)
val intent = Intent(Intent.ACTION_VIEW, engine!!.shareWalletUri)
val intent = Intent(Intent.ACTION_VIEW, engine?.shareWalletUri)
intent.addCategory(Intent.CATEGORY_DEFAULT)
startActivity(intent)
} catch (e: ActivityNotFoundException) {
@ -276,14 +284,8 @@ class LoadedWallet : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback
startVerify(lastTag)
}
override fun onResume() {
super.onResume()
nfcManager.onResume()
}
override fun onPause() {
super.onPause()
nfcManager.onPause()
if (timerHideErrorAndMessage != null) {
timerHideErrorAndMessage!!.cancel()
timerHideErrorAndMessage = null
@ -296,11 +298,6 @@ class LoadedWallet : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback
EventBus.getDefault().register(this)
}
override fun onStop() {
super.onStop()
nfcManager.onStop()
}
override fun onDestroy() {
EventBus.getDefault().unregister(this)
super.onDestroy()
@ -573,7 +570,7 @@ class LoadedWallet : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback
} else {
val validator = BalanceValidator()
// TODO why attest=false?
validator.Check(ctx, false)
validator.check(ctx, false)
context?.let { ContextCompat.getColor(it, validator.color) }?.let { tvBalanceLine1.setTextColor(it) }
tvBalanceLine1.text = validator.firstLine
tvBalanceLine2.text = validator.getSecondLine(false)
@ -670,6 +667,8 @@ class LoadedWallet : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback
requestCounter++
coinEngine!!.requestBalanceAndUnspentTransactions(
object : CoinEngine.BlockchainRequestsCallbacks {
override fun onComplete(success: Boolean) {
LOG.i(TAG, "requestBalanceAndUnspentTransactions onComplete: $success, request counter $requestCounter")
if (activity == null) return
@ -687,7 +686,12 @@ class LoadedWallet : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback
}
override fun allowAdvance(): Boolean {
return context?.let { UtilHelper.isOnline(it) }!!
return try {
context?.let { UtilHelper.isOnline(it) }!!
} catch (e: KotlinNullPointerException) {
e.printStackTrace()
false
}
}
}
)

View file

@ -4,6 +4,7 @@ import android.app.Activity
import android.content.Intent
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.os.Build
import android.os.Bundle
import androidx.core.content.ContextCompat
import android.text.Html
@ -22,6 +23,7 @@ import com.tangem.presentation.activity.*
import com.tangem.presentation.dialog.PINSwapWarningDialog
import com.tangem.presentation.event.DeletingWalletFinish
import com.tangem.tangemcard.android.data.PINStorage
import com.tangem.tangemcard.android.nfc.NfcLifecycleObserver
import com.tangem.tangemcard.android.reader.NfcManager
import com.tangem.tangemcard.data.TangemCard
import com.tangem.tangemcard.data.loadFromBundle
@ -50,8 +52,10 @@ class VerifyCard : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
nfcManager = NfcManager(activity, this)
ctx = TangemContext.loadFromBundle(activity, activity?.intent?.extras)
nfcManager = NfcManager(activity!!, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -60,7 +64,6 @@ class VerifyCard : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
updateViews()
srlVerifyCard.setOnRefreshListener { srlVerifyCard.isRefreshing = false }
@ -210,24 +213,9 @@ class VerifyCard : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback {
}
}
override fun onResume() {
super.onResume()
nfcManager.onResume()
}
override fun onPause() {
super.onPause()
nfcManager.onPause()
}
override fun onStop() {
super.onStop()
nfcManager.onStop()
}
override fun onTagDiscovered(tag: Tag?) {
try {
nfcManager.ignoreTag(tag)
nfcManager.ignoreTag(tag!!)
} catch (e: IOException) {
e.printStackTrace()
}
@ -270,7 +258,11 @@ class VerifyCard : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback {
tvIssuer.text = ctx.card!!.issuerDescription
tvCardRegistredDate.text = DateUtils.formatDateTime(null, ctx.card!!.personalizationDateTime.time, DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NUMERIC_DATE or DateUtils.FORMAT_SHOW_YEAR)
val html = Html.fromHtml(ctx.blockchainName)
@Suppress("DEPRECATION") val html = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
Html.fromHtml(ctx.blockchainName, Html.FROM_HTML_MODE_LEGACY)
else
Html.fromHtml(ctx.blockchainName)
tvBlockchain.text = html
tvValidationNode.text = ctx.coinData!!.validationNodeDescription

View file

@ -155,7 +155,7 @@ public class CryptoUtil {
// See Bitcoin Core's IsCanonicalSignature, https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
// A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
// Where R and S are not negative (their first byte has its highest bit not set), and not
// excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,
// excessively padded (do not init with a 0 byte, unless an otherwise negative number follows,
// in which case a single 0 byte is necessary and even required).
if (signature.length < 9 || signature.length > 73)
return false;

View file

@ -1,6 +1,5 @@
package com.tangem.util
import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color