Updated on 2026-08-14

This commit is contained in:
Tangem 2019-02-07 13:13:36 +03:00
parent 77c2ff30e5
commit 42b6efa391
9 changed files with 172 additions and 190 deletions

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

@ -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

@ -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

@ -64,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
@ -80,24 +76,37 @@ 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)
ctx = TangemContext.loadFromBundle(activity, activity?.intent?.extras)
nfcManager = NfcManager(activity, this)
nfcManager = NfcManager(activity!!, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
lastTag = activity?.intent?.getParcelableExtra(Constant.EXTRA_LAST_DISCOVERED_TAG)
@ -141,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) {
@ -561,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)
@ -607,10 +616,6 @@ class LoadedWallet : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback
btnExtract.isEnabled = false
btnExtract.backgroundTintList = inactiveColor
}
// //TODO why ???
// ctx.error = null
// ctx.message = null
}
private fun refresh() {

View file

@ -54,7 +54,7 @@ class VerifyCard : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback {
super.onCreate(savedInstanceState)
ctx = TangemContext.loadFromBundle(activity, activity?.intent?.extras)
nfcManager = NfcManager(activity, this)
nfcManager = NfcManager(activity!!, this)
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
}
@ -215,7 +215,7 @@ class VerifyCard : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback {
override fun onTagDiscovered(tag: Tag?) {
try {
nfcManager.ignoreTag(tag)
nfcManager.ignoreTag(tag!!)
} catch (e: IOException) {
e.printStackTrace()
}

View file

@ -1,11 +1,11 @@
buildscript {
ext.kotlin_version = '1.3.20'
ext.kotlin_version = '1.3.21'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
classpath 'com.android.tools.build:gradle:3.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

View file

@ -1,163 +0,0 @@
package com.tangem.tangemcard.android.reader;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.os.Build;
import android.os.Bundle;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.FragmentActivity;
import com.tangem.tangemcard.android.presentation.dialog.NfcEnableDialog;
import java.io.IOException;
public class NfcManager {
public static final String TAG = NfcManager.class.getSimpleName();
// reader mode flags: listen for type A (not B), skipping ndef check
private static final int READER_FLAGS = NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK | NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS;
private NfcAdapter nfcAdapter;
private NfcEnableDialog mEnableNfcDialog;
private FragmentActivity activity;
private NfcAdapter.ReaderCallback mReaderCallback;
private boolean broadcomWorkaround = false;
private static final int DELAY_PRESENCE = 1500;
public NfcManager(FragmentActivity activity, NfcAdapter.ReaderCallback readerCallback) {
this.activity = activity;
mReaderCallback = readerCallback;
nfcAdapter = NfcAdapter.getDefaultAdapter(activity);
}
public void onResume() {
// register broadcast receiver
IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
activity.registerReceiver(mBroadcastReceiver, filter);
if (nfcAdapter == null || !nfcAdapter.isEnabled())
showNFCEnableDialog();
else
enableReaderMode();
}
public void onPause() {
activity.unregisterReceiver(mBroadcastReceiver);
disableReaderMode();
}
public void onStop() {
if (mEnableNfcDialog != null) {
mEnableNfcDialog.dismiss();
}
}
public void ignoreTag(Tag tag) throws IOException {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// nfcAdapter.ignore(tag, 500, null, null);
// }else{
IsoDep isoDep = IsoDep.get(tag);
if (isoDep != null) {
isoDep.close();
}
// }
}
int errorCount = 0;
public void notifyReadResult(boolean success) {
// if (success) {
// errorCount = 0;
// } else {
// errorCount++;
// }
// if (errorCount >= 3) {
// disableReaderMode();
// nfcAdapter = null;
//// Toast.makeText(activity,"NFC restarted!",Toast.LENGTH_SHORT).show();
// activity.runOnUiThread(() -> {
// nfcAdapter = NfcAdapter.getDefaultAdapter(activity);
// enableReaderMode();
// });
// }
}
private void showNFCEnableDialog() {
mEnableNfcDialog = new NfcEnableDialog();
mEnableNfcDialog.show(activity.getSupportFragmentManager(), NfcEnableDialog.Companion.getTAG());
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action == null)
return;
if (action.equals(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)) {
int state = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE, NfcAdapter.STATE_ON);
if (state == NfcAdapter.STATE_ON || state == NfcAdapter.STATE_TURNING_ON) {
// Log.d(TAG, "state: " + state + " , dialog: " + mEnableNfcDialog);
if (mEnableNfcDialog != null) {
mEnableNfcDialog.dismiss();
}
if (state == NfcAdapter.STATE_ON) {
enableReaderMode();
}
} else {
if (mEnableNfcDialog == null || !mEnableNfcDialog.isVisible()) {
showNFCEnableDialog();
}
}
}
}
};
@TargetApi(Build.VERSION_CODES.KITKAT)
private void enableReaderMode() {
Bundle options = new Bundle();
if (broadcomWorkaround) {
/* This is a work around for some Broadcom chipsets that does
* the presence check by sending commands that interrupt the
* processing of the ongoing command.
*/
options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, DELAY_PRESENCE);
}
nfcAdapter.enableReaderMode(activity, mReaderCallback, READER_FLAGS, options);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private void disableReaderMode() {
if (nfcAdapter != null) {
nfcAdapter.disableReaderMode(activity);
}
}
private static final int REQUEST_NFC_PERMISSIONS = 1;
private static String[] PERMISSIONS_NFC = {
Manifest.permission.NFC
};
// checks if the app has NFC permission if the app does not has permission then the user will be prompted to grant permissions
public static void verifyPermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.NFC);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(activity, PERMISSIONS_NFC, REQUEST_NFC_PERMISSIONS);
}
}
}

View file

@ -0,0 +1,139 @@
package com.tangem.tangemcard.android.reader
import android.Manifest
import android.annotation.TargetApi
import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.nfc.tech.IsoDep
import android.os.Build
import android.os.Bundle
import androidx.core.app.ActivityCompat
import androidx.fragment.app.FragmentActivity
import com.tangem.tangemcard.android.presentation.dialog.NfcEnableDialog
import com.tangem.tangemcard.util.Log
import java.io.IOException
class NfcManager(private val activity: FragmentActivity, private val readerCallback: NfcAdapter.ReaderCallback) {
companion object {
val TAG: String = NfcManager::class.java.simpleName
// reader mode flags: listen for type A (not B), skipping ndef check
private const val READER_FLAGS = NfcAdapter.FLAG_READER_NFC_A or NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK or NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS
private const val DELAY_PRESENCE = 1500
private const val REQUEST_NFC_PERMISSIONS = 1
private val PERMISSIONS_NFC = arrayOf(Manifest.permission.NFC)
// checks if the app has NFC permission if the app does not has permission then the user will be prompted to grant permissions
fun verifyPermissions(activity: Activity) {
// check if we have write permission
val permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.NFC)
if (permission != PackageManager.PERMISSION_GRANTED) {
// we don't have permission so prompt the user
ActivityCompat.requestPermissions(activity, PERMISSIONS_NFC, REQUEST_NFC_PERMISSIONS)
}
}
}
private val nfcAdapter: NfcAdapter? = NfcAdapter.getDefaultAdapter(activity)
private var nfcEnableDialog: NfcEnableDialog? = null
private val broadcomWorkaround = false
internal var errorCount = 0
private val mBroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action ?: return
if (action == NfcAdapter.ACTION_ADAPTER_STATE_CHANGED) {
val state = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE, NfcAdapter.STATE_ON)
if (state == NfcAdapter.STATE_ON || state == NfcAdapter.STATE_TURNING_ON) {
Log.i(TAG, "state: $state , dialog: $nfcEnableDialog")
nfcEnableDialog?.dismiss()
if (state == NfcAdapter.STATE_ON)
enableReaderMode()
} else {
if (nfcEnableDialog == null || !nfcEnableDialog!!.isVisible)
showNFCEnableDialog()
}
}
}
}
fun onResume() {
// register broadcast receiver
val filter = IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)
activity.registerReceiver(mBroadcastReceiver, filter)
if (nfcAdapter == null || !nfcAdapter.isEnabled)
showNFCEnableDialog()
else
enableReaderMode()
}
fun onPause() {
activity.unregisterReceiver(mBroadcastReceiver)
disableReaderMode()
}
fun onStop() {
nfcEnableDialog?.dismiss()
}
@Throws(IOException::class)
fun ignoreTag(tag: Tag) {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// nfcAdapter.ignore(tag, 500, null, null);
// }else{
val isoDep = IsoDep.get(tag)
isoDep?.close()
// }
}
fun notifyReadResult(success: Boolean) {
// if (success) {
// errorCount = 0;
// } else {
// errorCount++;
// }
// if (errorCount >= 3) {
// disableReaderMode();
// nfcAdapter = null;
//// Toast.makeText(activity,"NFC restarted!",Toast.LENGTH_SHORT).show();
// activity.runOnUiThread(() -> {
// nfcAdapter = NfcAdapter.getDefaultAdapter(activity);
// enableReaderMode();
// });
// }
}
private fun showNFCEnableDialog() {
nfcEnableDialog = NfcEnableDialog()
nfcEnableDialog?.show(activity.supportFragmentManager, NfcEnableDialog.TAG)
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private fun enableReaderMode() {
val options = Bundle()
if (broadcomWorkaround) {
/* This is a work around for some Broadcom chipsets that does
* the presence check by sending commands that interrupt the
* processing of the ongoing command.
*/
options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, DELAY_PRESENCE)
}
nfcAdapter!!.enableReaderMode(activity, readerCallback, READER_FLAGS, options)
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private fun disableReaderMode() {
nfcAdapter?.disableReaderMode(activity)
}
}

View file

@ -1,10 +1,11 @@
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
def spongycastle_version = "1.56.0.0"
implementation 'com.madgag.spongycastle:core:1.56.0.0'
implementation 'com.madgag.spongycastle:prov:1.56.0.0'
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "com.madgag.spongycastle:core:$spongycastle_version"
implementation "com.madgag.spongycastle:prov:$spongycastle_version"
implementation 'net.i2p.crypto:eddsa:0.3.0'
}