Updated on 2026-08-14

This commit is contained in:
Tangem 2018-08-07 23:10:25 +03:00
parent 76b6259bfc
commit f22614ab8b
7 changed files with 383 additions and 426 deletions

View file

@ -17,7 +17,7 @@ public class ConfirmWithFingerprintTask extends AsyncTask<Void, Void, Boolean> {
public ConfirmWithFingerprintTask(SavePINActivity context) {
reference = new WeakReference<>(context);
reference.get().fingerprintHelper = new FingerprintHelper(reference.get());
reference.get().setFingerprintHelper(new FingerprintHelper(reference.get()));
}
@Override
@ -46,8 +46,7 @@ public class ConfirmWithFingerprintTask extends AsyncTask<Void, Void, Boolean> {
if (!success) {
Toast.makeText(savePINActivity, R.string.pin_save_fail, Toast.LENGTH_LONG).show();
} else {
savePINActivity.print("Confirm PIN action using fingerprint!");
savePINActivity.fingerprintHelper.startAuth(savePINActivity.fingerprintManager, savePINActivity.cryptoObject);
savePINActivity.getFingerprintHelper().startAuth(savePINActivity.getFingerprintManager(), savePINActivity.getCryptoObject());
}
}
@ -55,8 +54,8 @@ public class ConfirmWithFingerprintTask extends AsyncTask<Void, Void, Boolean> {
protected void onCancelled() {
SavePINActivity savePINActivity = reference.get();
if (savePINActivity.dFingerPrintConfirmation != null) {
savePINActivity.dFingerPrintConfirmation.cancel();
if (savePINActivity.getDFingerPrintConfirmation() != null) {
savePINActivity.getDFingerPrintConfirmation().cancel();
}
}

View file

@ -1,415 +0,0 @@
package com.tangem.presentation.activity;
import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Dialog;
import android.app.KeyguardManager;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.os.Bundle;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import com.tangem.data.network.task.save_pin.ConfirmWithFingerprintTask;
import com.tangem.domain.wallet.FingerprintHelper;
import com.tangem.domain.wallet.PINStorage;
import com.tangem.wallet.R;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
public class SavePINActivity extends AppCompatActivity implements FingerprintHelper.FingerprintHelperListener {
private TextView tvPIN;
private CheckBox chkUseFingerprint;
public ConfirmWithFingerprintTask confirmWithFingerprintTask;
private KeyStore keyStore;
private Cipher cipher;
public FingerprintManager fingerprintManager;
public FingerprintManager.CryptoObject cryptoObject;
public FingerprintHelper fingerprintHelper;
private boolean UsePIN2 = false;
private enum OnConfirmAction {Save, DeleteEncryptedAndSave, Delete}
private OnConfirmAction onConfirmAction;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_save_pin);
MainActivity.Companion.commonInit(getApplicationContext());
UsePIN2 = getIntent().getBooleanExtra("PIN2", false);
tvPIN = findViewById(R.id.pin);
OnClickListener onButtonNClick = view -> tvPIN.setText(String.format("%s%s", tvPIN.getText(), ((Button) view).getText()));
if (UsePIN2)
((TextView) findViewById(R.id.pin_prompt)).setText(R.string.enter_pin2_and_use_fingerprint_to_save_it);
else
((TextView) findViewById(R.id.pin_prompt)).setText(R.string.enter_pin_and_use_fingerprint_to_save_it);
chkUseFingerprint = findViewById(R.id.chkUseFingerprint);
if (UsePIN2) {
chkUseFingerprint.setChecked(true);
chkUseFingerprint.setEnabled(false);
} else {
chkUseFingerprint.setChecked(PINStorage.haveEncryptedPIN());
chkUseFingerprint.setEnabled(true);
}
Button btn0 = findViewById(R.id.btn0);
btn0.setOnClickListener(onButtonNClick);
Button btn1 = findViewById(R.id.btn1);
btn1.setOnClickListener(onButtonNClick);
Button btn2 = findViewById(R.id.btn2);
btn2.setOnClickListener(onButtonNClick);
Button btn3 = findViewById(R.id.btn3);
btn3.setOnClickListener(onButtonNClick);
Button btn4 = findViewById(R.id.btn4);
btn4.setOnClickListener(onButtonNClick);
Button btn5 = findViewById(R.id.btn5);
btn5.setOnClickListener(onButtonNClick);
Button btn6 = findViewById(R.id.btn6);
btn6.setOnClickListener(onButtonNClick);
Button btn7 = findViewById(R.id.btn7);
btn7.setOnClickListener(onButtonNClick);
Button btn8 = findViewById(R.id.btn8);
btn8.setOnClickListener(onButtonNClick);
Button btn9 = findViewById(R.id.btn9);
btn9.setOnClickListener(onButtonNClick);
Button btnBS = findViewById(R.id.btnBackspace);
btnBS.setOnClickListener(view -> {
String S = tvPIN.getText().toString();
if (S.length() > 0) {
tvPIN.setText(S.substring(0, S.length() - 1));
}
});
Button btnSave = findViewById(R.id.btnSavePIN);
btnSave.setOnClickListener(view -> doSavePIN());
Button btnDelete = findViewById(R.id.btnDeletePIN);
btnDelete.setOnClickListener(view -> doDeletePIN());
}
@Override
protected void onPause() {
super.onPause();
if (fingerprintHelper != null)
fingerprintHelper.cancel();
if (confirmWithFingerprintTask != null)
confirmWithFingerprintTask.cancel(true);
}
@Override
protected void onStop() {
super.onStop();
if (fingerprintHelper != null)
fingerprintHelper.cancel();
if (confirmWithFingerprintTask != null)
confirmWithFingerprintTask.cancel(true);
}
private void doSavePIN() {
if (confirmWithFingerprintTask != null) {
return;
}
tvPIN.setError(null);
String pin = tvPIN.getText().toString();
boolean cancel = false;
View focusView = null;
if (TextUtils.isEmpty(pin)) {
tvPIN.setError(getString(R.string.error_empty_pin));
focusView = tvPIN;
cancel = true;
}
if (cancel) {
focusView.requestFocus();
} else {
if (UsePIN2) {
if (!testFingerPrintSettings()) {
tvPIN.postDelayed(this::finish, 2000);
return;
}
onConfirmAction = OnConfirmAction.Save;
confirmWithFingerprintTask = new ConfirmWithFingerprintTask(SavePINActivity.this);
confirmWithFingerprintTask.execute((Void) null);
} else {
if (chkUseFingerprint.isChecked() || PINStorage.haveEncryptedPIN()) {
if (!testFingerPrintSettings()) {
tvPIN.postDelayed(this::finish, 2000);
return;
}
if (chkUseFingerprint.isChecked()) {
onConfirmAction = OnConfirmAction.Save;
} else {
onConfirmAction = OnConfirmAction.DeleteEncryptedAndSave;
}
// show a progress spinner, and kick off a background task to perform the user login attempt
//showProgress(true);
confirmWithFingerprintTask = new ConfirmWithFingerprintTask(SavePINActivity.this);
confirmWithFingerprintTask.execute((Void) null);
} else {
PINStorage.savePIN(tvPIN.getText().toString());
finish();
}
}
}
}
private void doDeletePIN() {
if (UsePIN2) {
if (PINStorage.haveEncryptedPIN2()) {
if (!testFingerPrintSettings()) {
tvPIN.postDelayed(this::finish, 2000);
return;
}
onConfirmAction = OnConfirmAction.Delete;
confirmWithFingerprintTask = new ConfirmWithFingerprintTask(SavePINActivity.this);
confirmWithFingerprintTask.execute((Void) null);
} else {
tvPIN.setText("");
finish();
}
} else {
if (chkUseFingerprint.isChecked() || PINStorage.haveEncryptedPIN()) {
if (!testFingerPrintSettings()) {
tvPIN.postDelayed(this::finish, 2000);
return;
}
onConfirmAction = OnConfirmAction.Delete;
confirmWithFingerprintTask = new ConfirmWithFingerprintTask(SavePINActivity.this);
confirmWithFingerprintTask.execute((Void) null);
} else {
tvPIN.setText("");
PINStorage.deletePIN();
finish();
}
}
}
@Override
public void authenticationFailed(String error) {
print(error);
}
@TargetApi(Build.VERSION_CODES.M)
@Override
public void authenticationSucceeded(FingerprintManager.AuthenticationResult result) {
print("Authentication succeeded!");
cipher = result.getCryptoObject().getCipher();
switch (onConfirmAction) {
case Save:
String textToEncrypt = tvPIN.getText().toString();
if (UsePIN2) {
PINStorage.saveEncryptedPIN2(cipher, textToEncrypt);
} else {
PINStorage.saveEncryptedPIN(cipher, textToEncrypt);
}
print(R.string.pin_save_success);
break;
case Delete:
if (UsePIN2) {
PINStorage.deleteEncryptedPIN2();
} else {
PINStorage.deleteEncryptedPIN();
PINStorage.deletePIN();
}
tvPIN.setText("");
break;
case DeleteEncryptedAndSave:
if (UsePIN2) {
PINStorage.deleteEncryptedPIN2();
PINStorage.saveEncryptedPIN2(cipher, tvPIN.getText().toString());
} else {
PINStorage.deleteEncryptedPIN();
PINStorage.savePIN(tvPIN.getText().toString());
}
break;
}
dFingerPrintConfirmation.dismiss();
finish();
}
public void print(String text) {
// Log.e("FP", text);
}
public void print(int id) {
print(getString(id));
}
@SuppressLint("NewApi")
private boolean testFingerPrintSettings() {
print("Testing Fingerprint Settings");
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
if (!keyguardManager.isKeyguardSecure()) {
print("User hasn't enabled Lock Screen");
Toast.makeText(getBaseContext(), "User hasn't enabled Lock Screen", Toast.LENGTH_LONG).show();
return false;
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
print("User hasn't granted permission to use Fingerprint");
Toast.makeText(getBaseContext(), "User hasn't granted permission to use Fingerprint", Toast.LENGTH_LONG).show();
return false;
}
if (!fingerprintManager.hasEnrolledFingerprints()) {
print("User hasn't registered any fingerprints");
Toast.makeText(getBaseContext(), "User hasn't registered any fingerprints", Toast.LENGTH_LONG).show();
return false;
}
print("Fingerprint authentication is set.\n");
return true;
}
public boolean getKeyStore() {
print("Getting keystore...");
try {
keyStore = KeyStore.getInstance(RequestPINActivity.KEYSTORE);
keyStore.load(null); // Create empty keystore
return true;
} catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
}
return false;
}
@TargetApi(Build.VERSION_CODES.M)
public boolean createNewKey(boolean forceCreate) {
print("Creating new key...");
try {
if (forceCreate)
keyStore.deleteEntry(RequestPINActivity.KEY_ALIAS);
if (!keyStore.containsAlias(RequestPINActivity.KEY_ALIAS)) {
KeyGenerator generator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, RequestPINActivity.KEYSTORE);
generator.init(new KeyGenParameterSpec.Builder(RequestPINActivity.KEY_ALIAS,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.setUserAuthenticationRequired(true)
.build()
);
generator.generateKey();
print("Key created.");
} else
print("Key exists.");
return true;
} catch (Exception e) {
print(e.getMessage());
}
return false;
}
public boolean getCipher() {
print("Getting cipher...");
try {
cipher = Cipher.getInstance(
KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
return true;
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
e.printStackTrace();
}
return false;
}
@TargetApi(Build.VERSION_CODES.M)
public boolean initCipher(int mode) {
print("Initializing cipher...");
try {
keyStore.load(null);
SecretKey keyspec = (SecretKey) keyStore.getKey(RequestPINActivity.KEY_ALIAS, null);
if (mode == Cipher.ENCRYPT_MODE) {
cipher.init(mode, keyspec);
} else {
byte[] iv = PINStorage.loadEncryptedIV();
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(mode, keyspec, ivspec);
}
return true;
} catch (KeyPermanentlyInvalidatedException e) {
e.printStackTrace();
createNewKey(true); // Retry after clearing entry
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
@TargetApi(Build.VERSION_CODES.M)
public boolean initCryptObject() {
print("Initializing crypt object...");
try {
cryptoObject = new FingerprintManager.CryptoObject(cipher);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public Dialog dFingerPrintConfirmation = null;
}

View file

@ -0,0 +1,370 @@
package com.tangem.presentation.activity
import android.Manifest
import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.app.Dialog
import android.app.KeyguardManager
import android.content.Context
import android.content.pm.PackageManager
import android.hardware.fingerprint.FingerprintManager
import android.os.Build
import android.os.Bundle
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyPermanentlyInvalidatedException
import android.security.keystore.KeyProperties
import android.support.v4.app.ActivityCompat
import android.support.v7.app.AppCompatActivity
import android.text.TextUtils
import android.view.View
import android.widget.Button
import android.widget.Toast
import com.tangem.data.network.task.save_pin.ConfirmWithFingerprintTask
import com.tangem.domain.wallet.FingerprintHelper
import com.tangem.domain.wallet.PINStorage
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_save_pin.*
import kotlinx.android.synthetic.main.layout_pin_buttons.*
import java.io.IOException
import java.security.KeyStore
import java.security.KeyStoreException
import java.security.NoSuchAlgorithmException
import java.security.cert.CertificateException
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.NoSuchPaddingException
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
class SavePINActivity : AppCompatActivity(), FingerprintHelper.FingerprintHelperListener {
private var confirmWithFingerprintTask: ConfirmWithFingerprintTask? = null
private var keyStore: KeyStore? = null
private var cipher: Cipher? = null
var fingerprintManager: FingerprintManager? = null
var cryptoObject: FingerprintManager.CryptoObject? = null
var fingerprintHelper: FingerprintHelper? = null
private var usePIN2 = false
private var onConfirmAction: OnConfirmAction? = null
var dFingerPrintConfirmation: Dialog? = null
private enum class OnConfirmAction {
Save, DeleteEncryptedAndSave, Delete
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_save_pin)
MainActivity.commonInit(applicationContext)
usePIN2 = intent.getBooleanExtra("PIN2", false)
if (usePIN2)
tvPinPrompt.text = getString(R.string.enter_pin2_and_use_fingerprint_to_save_it)
else
tvPinPrompt.text = getString(R.string.enter_pin_and_use_fingerprint_to_save_it)
if (usePIN2) {
cbUseFingerprint.isChecked = true
cbUseFingerprint.isEnabled = false
} else {
cbUseFingerprint.isChecked = PINStorage.haveEncryptedPIN()
cbUseFingerprint.isEnabled = true
}
// set listeners
btn0.setOnClickListener { buttonClick(btn0) }
btn1.setOnClickListener { buttonClick(btn1) }
btn2.setOnClickListener { buttonClick(btn2) }
btn3.setOnClickListener { buttonClick(btn3) }
btn4.setOnClickListener { buttonClick(btn4) }
btn5.setOnClickListener { buttonClick(btn5) }
btn6.setOnClickListener { buttonClick(btn6) }
btn7.setOnClickListener { buttonClick(btn7) }
btn8.setOnClickListener { buttonClick(btn8) }
btn9.setOnClickListener { buttonClick(btn9) }
btnBackspace.setOnClickListener {
val s = tvPin.text.toString()
if (s.isNotEmpty())
tvPin.text = s.substring(0, s.length - 1)
}
btnSavePIN.setOnClickListener { doSavePIN() }
btnDeletePIN.setOnClickListener { doDeletePIN() }
}
override fun onPause() {
super.onPause()
if (fingerprintHelper != null)
fingerprintHelper!!.cancel()
if (confirmWithFingerprintTask != null)
confirmWithFingerprintTask!!.cancel(true)
}
override fun onStop() {
super.onStop()
if (fingerprintHelper != null)
fingerprintHelper!!.cancel()
if (confirmWithFingerprintTask != null)
confirmWithFingerprintTask!!.cancel(true)
}
override fun authenticationFailed(error: String) {
}
@TargetApi(Build.VERSION_CODES.M)
override fun authenticationSucceeded(result: FingerprintManager.AuthenticationResult) {
cipher = result.cryptoObject.cipher
when (onConfirmAction) {
SavePINActivity.OnConfirmAction.Save -> {
val textToEncrypt = tvPin.text.toString()
if (usePIN2) {
PINStorage.saveEncryptedPIN2(cipher, textToEncrypt)
} else {
PINStorage.saveEncryptedPIN(cipher, textToEncrypt)
}
}
SavePINActivity.OnConfirmAction.Delete -> {
if (usePIN2) {
PINStorage.deleteEncryptedPIN2()
} else {
PINStorage.deleteEncryptedPIN()
PINStorage.deletePIN()
}
tvPin.text = ""
}
SavePINActivity.OnConfirmAction.DeleteEncryptedAndSave -> if (usePIN2) {
PINStorage.deleteEncryptedPIN2()
PINStorage.saveEncryptedPIN2(cipher, tvPin.text.toString())
} else {
PINStorage.deleteEncryptedPIN()
PINStorage.savePIN(tvPin.text.toString())
}
}
dFingerPrintConfirmation!!.dismiss()
finish()
}
fun getKeyStore(): Boolean {
try {
keyStore = KeyStore.getInstance(RequestPINActivity.KEYSTORE)
// create empty keystore
keyStore!!.load(null)
return true
} catch (e: KeyStoreException) {
e.printStackTrace()
} catch (e: CertificateException) {
e.printStackTrace()
} catch (e: NoSuchAlgorithmException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
}
return false
}
@TargetApi(Build.VERSION_CODES.M)
fun createNewKey(forceCreate: Boolean): Boolean {
try {
if (forceCreate)
keyStore!!.deleteEntry(RequestPINActivity.KEY_ALIAS)
if (!keyStore!!.containsAlias(RequestPINActivity.KEY_ALIAS)) {
val generator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, RequestPINActivity.KEYSTORE)
generator.init(KeyGenParameterSpec.Builder(RequestPINActivity.KEY_ALIAS,
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.setUserAuthenticationRequired(true)
.build()
)
generator.generateKey()
}
return true
} catch (e: Exception) {
e.printStackTrace()
}
return false
}
@SuppressLint("InlinedApi")
fun getCipher(): Boolean {
try {
cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7)
return true
} catch (e: NoSuchAlgorithmException) {
e.printStackTrace()
} catch (e: NoSuchPaddingException) {
e.printStackTrace()
}
return false
}
@TargetApi(Build.VERSION_CODES.M)
fun initCipher(mode: Int): Boolean {
try {
keyStore!!.load(null)
val keyspec = keyStore!!.getKey(RequestPINActivity.KEY_ALIAS, null) as SecretKey
if (mode == Cipher.ENCRYPT_MODE) {
cipher!!.init(mode, keyspec)
} else {
val iv = PINStorage.loadEncryptedIV()
val ivspec = IvParameterSpec(iv)
cipher!!.init(mode, keyspec, ivspec)
}
return true
} catch (e: KeyPermanentlyInvalidatedException) {
e.printStackTrace()
// retry after clearing entry
createNewKey(true)
} catch (e: Exception) {
e.printStackTrace()
}
return false
}
@TargetApi(Build.VERSION_CODES.M)
fun initCryptObject(): Boolean {
try {
cryptoObject = FingerprintManager.CryptoObject(cipher!!)
return true
} catch (e: Exception) {
e.printStackTrace()
}
return false
}
@SuppressLint("SetTextI18n")
private fun buttonClick(button: Button) {
tvPin.text = String.format("%s%s", tvPin.text, button.text)
}
private fun doSavePIN() {
if (confirmWithFingerprintTask != null) {
return
}
tvPin.error = null
val pin = tvPin.text.toString()
var cancel = false
var focusView: View? = null
if (TextUtils.isEmpty(pin)) {
tvPin.error = getString(R.string.error_empty_pin)
focusView = tvPin
cancel = true
}
if (cancel) {
focusView!!.requestFocus()
} else {
if (usePIN2) {
if (!testFingerPrintSettings()) {
tvPin.postDelayed({ this.finish() }, 2000)
return
}
onConfirmAction = OnConfirmAction.Save
confirmWithFingerprintTask = ConfirmWithFingerprintTask(this@SavePINActivity)
confirmWithFingerprintTask!!.execute(null as Void?)
} else {
if (cbUseFingerprint.isChecked || PINStorage.haveEncryptedPIN()) {
if (!testFingerPrintSettings()) {
tvPin.postDelayed({ this.finish() }, 2000)
return
}
onConfirmAction = if (cbUseFingerprint.isChecked) {
OnConfirmAction.Save
} else {
OnConfirmAction.DeleteEncryptedAndSave
}
// show a progress spinner, and kick off a background task to perform the user login attempt
//showProgress(true);
confirmWithFingerprintTask = ConfirmWithFingerprintTask(this@SavePINActivity)
confirmWithFingerprintTask!!.execute(null as Void?)
} else {
PINStorage.savePIN(tvPin.text.toString())
finish()
}
}
}
}
private fun doDeletePIN() {
if (usePIN2) {
if (PINStorage.haveEncryptedPIN2()) {
if (!testFingerPrintSettings()) {
tvPin.postDelayed({ this.finish() }, 2000)
return
}
onConfirmAction = OnConfirmAction.Delete
confirmWithFingerprintTask = ConfirmWithFingerprintTask(this@SavePINActivity)
confirmWithFingerprintTask!!.execute(null as Void?)
} else {
tvPin.text = ""
finish()
}
} else {
if (cbUseFingerprint.isChecked || PINStorage.haveEncryptedPIN()) {
if (!testFingerPrintSettings()) {
tvPin.postDelayed({ this.finish() }, 2000)
return
}
onConfirmAction = OnConfirmAction.Delete
confirmWithFingerprintTask = ConfirmWithFingerprintTask(this@SavePINActivity)
confirmWithFingerprintTask!!.execute(null as Void?)
} else {
tvPin.text = ""
PINStorage.deletePIN()
finish()
}
}
}
@SuppressLint("NewApi")
private fun testFingerPrintSettings(): Boolean {
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
fingerprintManager = getSystemService(Context.FINGERPRINT_SERVICE) as FingerprintManager
if (!keyguardManager.isKeyguardSecure) {
Toast.makeText(baseContext, R.string.user_has_not_enabled_lock_screen, Toast.LENGTH_LONG).show()
return false
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(baseContext, R.string.user_has_not_granted_permission_to_use_fingerprint, Toast.LENGTH_LONG).show()
return false
}
if (!fingerprintManager!!.hasEnrolledFingerprints()) {
Toast.makeText(baseContext, R.string.user_has_not_registered_any_fingerprints, Toast.LENGTH_LONG).show()
return false
}
return true
}
}

View file

@ -62,7 +62,7 @@ public class SendTransactionActivity extends AppCompatActivity {
public boolean onKeyDown(int keycode, KeyEvent e) {
switch (keycode) {
case KeyEvent.KEYCODE_BACK:
Toast.makeText(getBaseContext(), "Please wait while the payment is sent...", Toast.LENGTH_LONG).show();
Toast.makeText(this, R.string.please_wait, Toast.LENGTH_LONG).show();
return true;
}
return super.onKeyDown(keycode, e);
@ -77,7 +77,7 @@ public class SendTransactionActivity extends AppCompatActivity {
public void finishWithSuccess() {
Intent intent = new Intent();
intent.putExtra("message", "Transaction has been successfully signed and sent to blockchain node. Wallet balance will be updated in a while");
intent.putExtra("message", getString(R.string.transaction_has_been_successfully_signed));
setResult(MainActivity.RESULT_OK, intent);
finish();
}

View file

@ -7,7 +7,7 @@
tools:context="com.tangem.presentation.activity.SavePINActivity">
<TextView
android:id="@+id/pin"
android:id="@+id/tvPin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
@ -19,7 +19,7 @@
tools:ignore="TextViewEdits" />
<TextView
android:id="@+id/pin_prompt"
android:id="@+id/tvPinPrompt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
@ -45,7 +45,7 @@
android:orientation="vertical">
<CheckBox
android:id="@+id/chkUseFingerprint"
android:id="@+id/cbUseFingerprint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"

View file

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"

View file

@ -145,6 +145,7 @@
<!-- SendTransactionActivity -->
<string name="please_wait">Please wait while the payment is sent…</string>
<string name="transaction_has_been_successfully_signed">Transaction has been successfully signed and sent to blockchain node. Wallet balance will be updated in a while</string>
<!-- PreparePaymentActivity -->
<string name="not_enough_funds_on_your_card">Not enough funds on your card</string>
@ -205,5 +206,8 @@
<string name="delete">Delete</string>
<string name="protect_with_fingerprint">Protect with fingerprint</string>
<string name="touch_fingerprint_scanner_to_confirm">Touch fingerprint scanner to confirm</string>
<string name="user_has_not_enabled_lock_screen">User hasn\'t enabled Lock Screen</string>
<string name="user_has_not_granted_permission_to_use_fingerprint">User hasn\'t granted permission to use Fingerprint</string>
<string name="user_has_not_registered_any_fingerprints">User hasn\'t registered any fingerprints</string>
</resources>