|
|
@ -11,6 +11,7 @@ import android.os.Build; |
|
|
|
import android.os.Bundle; |
|
|
|
import android.os.CountDownTimer; |
|
|
|
import android.os.Handler; |
|
|
|
import android.security.keystore.KeyPermanentlyInvalidatedException; |
|
|
|
import android.support.graphics.drawable.AnimatedVectorDrawableCompat; |
|
|
|
import android.support.v4.content.ContextCompat; |
|
|
|
import android.support.v4.view.GestureDetectorCompat; |
|
|
@ -103,13 +104,11 @@ public class TransactionPasswordPromptActivity extends BaseActivity implements S |
|
|
|
public static final String PAYMENT_TYPE_BUNDLE_KEY = "bundleKeyPaymentType"; |
|
|
|
public static final String SELECTED_AMT_FOR_OTP_BUNDLE_KEY = "bundleKeySelectedAmtOtp"; |
|
|
|
public static final String SELECTED_KFTC_ID_FOR_OTP_BUNDLE_KEY = "bundleKeySelectedKFTCId"; |
|
|
|
private String paymentType; |
|
|
|
// private String paymentType; |
|
|
|
private TransactionPasswordPromptV2PresenterInterface presenter; |
|
|
|
private CountDownTimer countDownTimer; |
|
|
|
private AnimatedVectorDrawableCompat fingerPrintAVDCompat; |
|
|
|
private Disposable fingerPrintReaderSubs; |
|
|
|
|
|
|
|
String TAG = "FingerPrintObserver"; |
|
|
|
|
|
|
|
@Override |
|
|
|
protected void onCreate(Bundle savedInstanceState) { |
|
|
@ -139,9 +138,8 @@ public class TransactionPasswordPromptActivity extends BaseActivity implements S |
|
|
|
} |
|
|
|
|
|
|
|
private void preInit() { |
|
|
|
presenter = new TransactionPasswordPromptV2Presenter(this); |
|
|
|
paymentType = getIntent().getStringExtra(PAYMENT_TYPE_BUNDLE_KEY); |
|
|
|
if (checkIfRequiredOTPScreen()) { |
|
|
|
presenter = new TransactionPasswordPromptV2Presenter(this,getIntent().getStringExtra(PAYMENT_TYPE_BUNDLE_KEY)); |
|
|
|
if (presenter.checkIfRequiredOTPScreen()) { |
|
|
|
presenter.updateCountdown(getIntent().getLongExtra(OTP_COUNTDOWN_VALUE, -1)); |
|
|
|
presenter.updateSelectedAmount(getIntent().getStringExtra(SELECTED_AMT_FOR_OTP_BUNDLE_KEY)); |
|
|
|
presenter.updateSelectedKftcId(getIntent().getStringExtra(SELECTED_KFTC_ID_FOR_OTP_BUNDLE_KEY)); |
|
|
@ -154,52 +152,24 @@ public class TransactionPasswordPromptActivity extends BaseActivity implements S |
|
|
|
securityKeypadListener = new SecurityKeypadListener(); |
|
|
|
myViewGestureDetector = new TransactionPasswordPromptActivityGestureDetector(); |
|
|
|
gestureDetector = new GestureDetectorCompat(this, myViewGestureDetector); |
|
|
|
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); |
|
|
|
|
|
|
|
try { |
|
|
|
securityKeyboardManager = new SecurityKeyboardManager(this); |
|
|
|
SecurityKeypadRequestParamBuilder request = new SecurityKeypadRequestParamBuilder(this); |
|
|
|
request.disableKeyPadEffect(false); |
|
|
|
if (checkIfRequiredOTPScreen()) { |
|
|
|
request.setKeypadType(TransKeyActivity.mTK_TYPE_KEYPAD_NUMBER); |
|
|
|
request.setHintString(getString(R.string.otp_password_hint_text)); |
|
|
|
title.setText(getString(R.string.enter_otp_password_text)); |
|
|
|
request.setMaxLength(4); |
|
|
|
ballonView.setVisibility(View.INVISIBLE); |
|
|
|
passwordPromptImageView.setBackgroundResource(R.drawable.ic_penny_test_pending); |
|
|
|
|
|
|
|
} else { |
|
|
|
request.setHintString(getString(R.string.password_text)); |
|
|
|
title.setText(getString(R.string.enter_login_password_text)); |
|
|
|
resendRequest.setVisibility(View.INVISIBLE); |
|
|
|
setupFingerPrintIconIfRequired(); |
|
|
|
|
|
|
|
} |
|
|
|
securityKeyboardManager.bindWithSecurityWidgetView(securityKeyboardView) |
|
|
|
.setBallonView(ballonView) |
|
|
|
.setKeyboardContainer(keypadContainer) |
|
|
|
.setRequestParams(request) |
|
|
|
.setActionListener(securityKeypadListener) |
|
|
|
.build(); |
|
|
|
|
|
|
|
presenter.verifyTxnType(); |
|
|
|
} catch (Exception e) { |
|
|
|
e.printStackTrace(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void setupFingerPrintIconIfRequired() { |
|
|
|
if (presenter.checkIfUserHasEnabledBiometricAuth()) { |
|
|
|
orTextView.setVisibility(View.VISIBLE); |
|
|
|
fingerPrintAVDCompat = AnimatedVectorDrawableCompat.create(this, R.drawable.avd_fingerprint_off_to_on); |
|
|
|
} else { |
|
|
|
passwordPromptImageView.setBackgroundResource(R.drawable.ic_penny_test_pending); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void performDefaultAction(Bundle savedInstanceState) { |
|
|
|
securityKeyboardManager.showKeyboard(); |
|
|
|
if (checkIfRequiredOTPScreen()) { |
|
|
|
if (presenter.checkIfRequiredOTPScreen()) { |
|
|
|
new Handler().postDelayed(() -> { |
|
|
|
presenter.getOtp(); |
|
|
|
}, 400); |
|
|
@ -207,9 +177,7 @@ public class TransactionPasswordPromptActivity extends BaseActivity implements S |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
private boolean checkIfRequiredOTPScreen() { |
|
|
|
return paymentType.equalsIgnoreCase("autodebit"); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
public boolean dispatchTouchEvent(MotionEvent ev) { |
|
|
@ -234,83 +202,95 @@ public class TransactionPasswordPromptActivity extends BaseActivity implements S |
|
|
|
protected void onStart() { |
|
|
|
super.onStart(); |
|
|
|
securityKeyboardView.setSecurityKeyboardFocusStateListener(this); |
|
|
|
if (checkIfRequiredOTPScreen()) |
|
|
|
if (presenter.checkIfRequiredOTPScreen()) |
|
|
|
resendRequest.setOnClickListener(this); |
|
|
|
else if (presenter.checkIfUserHasEnabledBiometricAuth()&&(fingerPrintReaderSubs==null||fingerPrintReaderSubs.isDisposed())) |
|
|
|
fingerPrintReaderSubs = startObservingFingerPrintScanner(); |
|
|
|
else |
|
|
|
presenter.startObservingFingerPrintIfRequired(true); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
protected void onStop() { |
|
|
|
super.onStop(); |
|
|
|
securityKeyboardView.setSecurityKeyboardFocusStateListener(null); |
|
|
|
if (checkIfRequiredOTPScreen()) |
|
|
|
if (presenter.checkIfRequiredOTPScreen()) |
|
|
|
resendRequest.setOnClickListener(null); |
|
|
|
if (fingerPrintReaderSubs != null && !fingerPrintReaderSubs.isDisposed()) |
|
|
|
fingerPrintReaderSubs.dispose(); |
|
|
|
|
|
|
|
else |
|
|
|
presenter.startObservingFingerPrintIfRequired(false); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
protected void onResume() { |
|
|
|
super.onResume(); |
|
|
|
animateFingerPrintAppearAnimationIfRequired(true); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
protected void onPause() { |
|
|
|
super.onPause(); |
|
|
|
animateFingerPrintAppearAnimationIfRequired(false); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
@SuppressLint("NewApi") |
|
|
|
private void animateFingerPrintAppearAnimationIfRequired(boolean action) { |
|
|
|
if (!checkIfRequiredOTPScreen() && presenter.checkIfUserHasEnabledBiometricAuth() && action) { |
|
|
|
new Handler().postDelayed(() -> { |
|
|
|
@Override |
|
|
|
public void animateFingerPrintAppearAnimationIfRequired(boolean action) { |
|
|
|
if (action) { |
|
|
|
if (fingerPrintAVDCompat != null && !fingerPrintAVDCompat.isRunning()) { |
|
|
|
passwordPromptImageView.setImageDrawable(fingerPrintAVDCompat); |
|
|
|
fingerPrintAVDCompat.start(); |
|
|
|
} |
|
|
|
|
|
|
|
}, 400); |
|
|
|
} else { |
|
|
|
new Handler().postDelayed(() -> { |
|
|
|
passwordPromptImageView.setImageDrawable(null); |
|
|
|
}, 200); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private Disposable startObservingFingerPrintScanner() { |
|
|
|
return SecurityUtils.decryptSecret(this, presenter.getSecretKey()) |
|
|
|
.subscribeOn(Schedulers.io()) |
|
|
|
.flatMap(authentication -> { |
|
|
|
switch (authentication.getResult()) { |
|
|
|
case FAILED: |
|
|
|
return io.reactivex.Observable.error(new SecurityUtils.FailedFingerPrintException(getString(R.string.fingerprint_not_recognized))); |
|
|
|
case HELP: |
|
|
|
return io.reactivex.Observable.error(new SecurityUtils.SensorNotReadyException(authentication.getMessage())); |
|
|
|
case AUTHENTICATED: |
|
|
|
return Observable.just(authentication); |
|
|
|
default: |
|
|
|
return io.reactivex.Observable.error(new Throwable(authentication.getMessage())); |
|
|
|
} |
|
|
|
|
|
|
|
}) |
|
|
|
.observeOn(AndroidSchedulers.mainThread()) |
|
|
|
.retryWhen(errors->errors.flatMap( |
|
|
|
error->{ |
|
|
|
if(error instanceof SecurityUtils.FailedFingerPrintException || error instanceof SecurityUtils.SensorNotReadyException) |
|
|
|
{ |
|
|
|
showToastMessage(error.getMessage()); |
|
|
|
return Observable.timer(100,TimeUnit.MILLISECONDS); |
|
|
|
} |
|
|
|
return Observable.error(error); |
|
|
|
} |
|
|
|
)) |
|
|
|
.subscribeWith(new FingerPrintScannerObserver()); |
|
|
|
@Override |
|
|
|
public void setupAutoDebitTxnPasswordPromptView() { |
|
|
|
SecurityKeypadRequestParamBuilder request = new SecurityKeypadRequestParamBuilder(this); |
|
|
|
request.disableKeyPadEffect(false); |
|
|
|
request.setKeypadType(TransKeyActivity.mTK_TYPE_KEYPAD_NUMBER); |
|
|
|
request.setHintString(getString(R.string.otp_password_hint_text)); |
|
|
|
title.setText(getString(R.string.enter_otp_password_text)); |
|
|
|
request.setMaxLength(4); |
|
|
|
ballonView.setVisibility(View.INVISIBLE); |
|
|
|
securityKeyboardManager.bindWithSecurityWidgetView(securityKeyboardView) |
|
|
|
.setBallonView(ballonView) |
|
|
|
.setKeyboardContainer(keypadContainer) |
|
|
|
.setRequestParams(request) |
|
|
|
.setActionListener(securityKeypadListener) |
|
|
|
.build(); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void setupWalletTxnPasswordPromptView() { |
|
|
|
SecurityKeypadRequestParamBuilder request = new SecurityKeypadRequestParamBuilder(this); |
|
|
|
request.disableKeyPadEffect(false); |
|
|
|
request.setHintString(getString(R.string.password_text)); |
|
|
|
title.setText(getString(R.string.enter_login_password_text)); |
|
|
|
resendRequest.setVisibility(View.INVISIBLE); |
|
|
|
securityKeyboardManager.bindWithSecurityWidgetView(securityKeyboardView) |
|
|
|
.setBallonView(ballonView) |
|
|
|
.setKeyboardContainer(keypadContainer) |
|
|
|
.setRequestParams(request) |
|
|
|
.setActionListener(securityKeypadListener) |
|
|
|
.build(); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void addFingerprintIcon(boolean action) { |
|
|
|
if(action) { |
|
|
|
orTextView.setVisibility(View.VISIBLE); |
|
|
|
fingerPrintAVDCompat = AnimatedVectorDrawableCompat.create(this, R.drawable.avd_fingerprint_off_to_on); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
orTextView.setVisibility(View.GONE); |
|
|
|
fingerPrintAVDCompat=null; |
|
|
|
passwordPromptImageView.setImageDrawable(null); |
|
|
|
passwordPromptImageView.setBackgroundResource(R.drawable.ic_penny_test_pending); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
public void onSecurityViewRecievedFocus() { |
|
|
|
if (securityKeyboardManager != null && !securityKeyboardManager.isKeyboardVisible()) |
|
|
@ -364,7 +344,7 @@ public class TransactionPasswordPromptActivity extends BaseActivity implements S |
|
|
|
} |
|
|
|
|
|
|
|
private void updateIntentOnCanellationAndFinish() { |
|
|
|
boolean result = checkIfRequiredOTPScreen(); |
|
|
|
boolean result = presenter.checkIfRequiredOTPScreen(); |
|
|
|
if (result) { |
|
|
|
Intent backIntent = new Intent(); |
|
|
|
setResult(RESULT_CANCELED, backIntent); |
|
|
@ -395,7 +375,13 @@ public class TransactionPasswordPromptActivity extends BaseActivity implements S |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
public void onBiometricAuthSuccess(String decPassword) { |
|
|
|
Intent returnIntent = new Intent(); |
|
|
|
returnIntent.putExtra(TRANSACTION_PWD_ENC_DATA, decPassword); |
|
|
|
setResult(Activity.RESULT_OK, returnIntent); |
|
|
|
finish(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
@ -423,7 +409,7 @@ public class TransactionPasswordPromptActivity extends BaseActivity implements S |
|
|
|
setResult(Activity.RESULT_OK, returnIntent); |
|
|
|
finish(); |
|
|
|
} else { |
|
|
|
if (checkIfRequiredOTPScreen()) |
|
|
|
if (presenter.checkIfRequiredOTPScreen()) |
|
|
|
passwordErrorTxt.setErrorText(getString(R.string.otp_empty_error)); |
|
|
|
else |
|
|
|
passwordErrorTxt.setErrorText(getString(R.string.password_empty_error)); |
|
|
@ -475,26 +461,4 @@ public class TransactionPasswordPromptActivity extends BaseActivity implements S |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
class FingerPrintScannerObserver extends DisposableObserver<FingerprintDecryptionResult> { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
public void onNext(FingerprintDecryptionResult fingerprintAuthenticationResult) { |
|
|
|
Intent returnIntent = new Intent(); |
|
|
|
returnIntent.putExtra(TRANSACTION_PWD_ENC_DATA, fingerprintAuthenticationResult.getDecrypted()); |
|
|
|
setResult(Activity.RESULT_OK, returnIntent); |
|
|
|
finish(); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void onError(Throwable e) { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void onComplete() { |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |