From 42b6efa391b5ca5467a337573b923b01dd2146b5 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 7 Feb 2019 13:13:36 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../java/com/tangem/data/LogFileProvider.java | 2 +- app/src/main/java/com/tangem/data/Logger.java | 2 +- .../domain/wallet/BalanceValidator.java | 2 +- .../presentation/fragment/LoadedWallet.kt | 39 +++-- .../presentation/fragment/VerifyCard.kt | 4 +- build.gradle | 4 +- .../tangemcard/android/reader/NfcManager.java | 163 ------------------ .../tangemcard/android/reader/NfcManager.kt | 139 +++++++++++++++ tangemcard-common/build.gradle | 7 +- 9 files changed, 172 insertions(+), 190 deletions(-) delete mode 100644 tangemcard-android/src/main/java/com/tangem/tangemcard/android/reader/NfcManager.java create mode 100644 tangemcard-android/src/main/java/com/tangem/tangemcard/android/reader/NfcManager.kt diff --git a/app/src/main/java/com/tangem/data/LogFileProvider.java b/app/src/main/java/com/tangem/data/LogFileProvider.java index 1c95cf0459..48c9b1ff56 100644 --- a/app/src/main/java/com/tangem/data/LogFileProvider.java +++ b/app/src/main/java/com/tangem/data/LogFileProvider.java @@ -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 diff --git a/app/src/main/java/com/tangem/data/Logger.java b/app/src/main/java/com/tangem/data/Logger.java index 3c1aece038..9196d9987c 100644 --- a/app/src/main/java/com/tangem/data/Logger.java +++ b/app/src/main/java/com/tangem/data/Logger.java @@ -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) { diff --git a/app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java b/app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java index e5ada4f494..a40ef82c03 100644 --- a/app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java +++ b/app/src/main/java/com/tangem/domain/wallet/BalanceValidator.java @@ -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(); diff --git a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt index 1453766033..7d59bc7143 100644 --- a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt +++ b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt @@ -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() { diff --git a/app/src/main/java/com/tangem/presentation/fragment/VerifyCard.kt b/app/src/main/java/com/tangem/presentation/fragment/VerifyCard.kt index 2cf643d5f3..4afa6e42ab 100644 --- a/app/src/main/java/com/tangem/presentation/fragment/VerifyCard.kt +++ b/app/src/main/java/com/tangem/presentation/fragment/VerifyCard.kt @@ -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() } diff --git a/build.gradle b/build.gradle index 3648e89e4f..2bfb6ce8b6 100644 --- a/build.gradle +++ b/build.gradle @@ -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" } } diff --git a/tangemcard-android/src/main/java/com/tangem/tangemcard/android/reader/NfcManager.java b/tangemcard-android/src/main/java/com/tangem/tangemcard/android/reader/NfcManager.java deleted file mode 100644 index eff969ccec..0000000000 --- a/tangemcard-android/src/main/java/com/tangem/tangemcard/android/reader/NfcManager.java +++ /dev/null @@ -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); - } - } - -} \ No newline at end of file diff --git a/tangemcard-android/src/main/java/com/tangem/tangemcard/android/reader/NfcManager.kt b/tangemcard-android/src/main/java/com/tangem/tangemcard/android/reader/NfcManager.kt new file mode 100644 index 0000000000..5216e86052 --- /dev/null +++ b/tangemcard-android/src/main/java/com/tangem/tangemcard/android/reader/NfcManager.kt @@ -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) + } + +} \ No newline at end of file diff --git a/tangemcard-common/build.gradle b/tangemcard-common/build.gradle index 6dc4a7ca41..98c83e33a7 100644 --- a/tangemcard-common/build.gradle +++ b/tangemcard-common/build.gradle @@ -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' }