diff --git a/app/src/main/java/com/tangem/data/network/task/save_pin/ConfirmWithFingerprintTask.java b/app/src/main/java/com/tangem/data/network/task/save_pin/ConfirmWithFingerprintTask.java index 43b18fdf03..ca11e15bfc 100644 --- a/app/src/main/java/com/tangem/data/network/task/save_pin/ConfirmWithFingerprintTask.java +++ b/app/src/main/java/com/tangem/data/network/task/save_pin/ConfirmWithFingerprintTask.java @@ -17,7 +17,7 @@ public class ConfirmWithFingerprintTask extends AsyncTask { 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 { 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 { protected void onCancelled() { SavePINActivity savePINActivity = reference.get(); - if (savePINActivity.dFingerPrintConfirmation != null) { - savePINActivity.dFingerPrintConfirmation.cancel(); + if (savePINActivity.getDFingerPrintConfirmation() != null) { + savePINActivity.getDFingerPrintConfirmation().cancel(); } } diff --git a/app/src/main/java/com/tangem/presentation/activity/SavePINActivity.java b/app/src/main/java/com/tangem/presentation/activity/SavePINActivity.java deleted file mode 100644 index 6e3d01b7d5..0000000000 --- a/app/src/main/java/com/tangem/presentation/activity/SavePINActivity.java +++ /dev/null @@ -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; - -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/presentation/activity/SavePINActivity.kt b/app/src/main/java/com/tangem/presentation/activity/SavePINActivity.kt new file mode 100644 index 0000000000..24d07529c1 --- /dev/null +++ b/app/src/main/java/com/tangem/presentation/activity/SavePINActivity.kt @@ -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 + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.java b/app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.java index d537bcb7f4..0059865c12 100644 --- a/app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.java +++ b/app/src/main/java/com/tangem/presentation/activity/SendTransactionActivity.java @@ -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(); } diff --git a/app/src/main/res/layout/activity_save_pin.xml b/app/src/main/res/layout/activity_save_pin.xml index ac37497677..842e3ac388 100644 --- a/app/src/main/res/layout/activity_save_pin.xml +++ b/app/src/main/res/layout/activity_save_pin.xml @@ -7,7 +7,7 @@ tools:context="com.tangem.presentation.activity.SavePINActivity"> Please wait while the payment is sent… + Transaction has been successfully signed and sent to blockchain node. Wallet balance will be updated in a while Not enough funds on your card @@ -205,5 +206,8 @@ Delete Protect with fingerprint Touch fingerprint scanner to confirm + User hasn\'t enabled Lock Screen + User hasn\'t granted permission to use Fingerprint + User hasn\'t registered any fingerprints \ No newline at end of file