Browse Source

ga .

master
Preyea Regmi 5 years ago
parent
commit
230a6a072d
  1. 44
      app/src/main/java/com/gmeremit/online/gmeremittance_native/base/PrivilegedGateway.java
  2. 18
      app/src/main/java/com/gmeremit/online/gmeremittance_native/base/PrivilegedGatewayInterface.java
  3. 9
      app/src/main/java/com/gmeremit/online/gmeremittance_native/changepasswordV2/gateway/ChangePasswordV2Gateway.java
  4. 5
      app/src/main/java/com/gmeremit/online/gmeremittance_native/changepasswordV2/presenter/ChangePasswordV2Presenter.java
  5. 31
      app/src/main/java/com/gmeremit/online/gmeremittance_native/loginV2/gateway/LoginV2Gateway.java
  6. 9
      app/src/main/java/com/gmeremit/online/gmeremittance_native/loginV2/presenter/LoginV2InteractorInterface.java
  7. 9
      app/src/main/java/com/gmeremit/online/gmeremittance_native/loginV2/presenter/LoginV2Presenter.java
  8. 2
      app/src/main/java/com/gmeremit/online/gmeremittance_native/loginV2/presenter/LoginV2PresenterInterface.java
  9. 10
      app/src/main/java/com/gmeremit/online/gmeremittance_native/loginV2/view/LoginV2Activity.java
  10. 5
      app/src/main/java/com/gmeremit/online/gmeremittance_native/settings/view/FingerPrintAuthPromptDialog.java
  11. 82
      app/src/main/java/com/gmeremit/online/gmeremittance_native/settings/view/SettingsView.java
  12. 24
      app/src/main/java/com/gmeremit/online/gmeremittance_native/transactionpasspromt/gateway/TransactionPasswordPromptV2Gateway.java
  13. 9
      app/src/main/java/com/gmeremit/online/gmeremittance_native/transactionpasspromt/presenter/TransactionPasswordPromptV2InteractorInterface.java
  14. 106
      app/src/main/java/com/gmeremit/online/gmeremittance_native/transactionpasspromt/presenter/TransactionPasswordPromptV2Presenter.java
  15. 12
      app/src/main/java/com/gmeremit/online/gmeremittance_native/transactionpasspromt/presenter/TransactionPasswordPromptV2PresenterInterface.java
  16. 182
      app/src/main/java/com/gmeremit/online/gmeremittance_native/transactionpasspromt/view/TransactionPasswordPromptActivity.java
  17. 1
      app/src/main/res/values/strings.xml

44
app/src/main/java/com/gmeremit/online/gmeremittance_native/base/PrivilegedGateway.java

@ -167,4 +167,48 @@ public abstract class PrivilegedGateway implements PrivilegedGatewayInterface {
private boolean isValidString(String word) {
return word != null && word.length() >= 1;
}
@Override
public void persistUserId(String encrypted) {
GmeApplication.getStorage().edit().putString(PrefKeys.APP_USER_ID_SECRET_KEY,encrypted).apply();
}
@Override
public void persistUserPwd(String encrypted) {
GmeApplication.getStorage().edit().putString(PrefKeys.APP_USER_SECRET_KEY,encrypted).apply();
}
@Override
public boolean isFingerPrintAuthEnabled() {
return GmeApplication.getStorage().getBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED,false);
}
@Override
public String getPersistedUserId() {
return GmeApplication.getStorage().getString(PrefKeys.APP_USER_ID_SECRET_KEY,null);
}
@Override
public String getPersistedUserPwd() {
return GmeApplication.getStorage().getString(PrefKeys.APP_USER_SECRET_KEY,null);
}
@Override
public void turnOffFingerprintAuth(boolean action) {
GmeApplication.getStorage().edit().putBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED,!action).apply();
}
@Override
public void flushBiometricData() {
SharedPreferences.Editor editor = GmeApplication.getStorage().edit();
editor.putString(PrefKeys.APP_USER_ID_SECRET_KEY,null);
editor.putBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED,false);
editor.putString(PrefKeys.APP_USER_SECRET_KEY,null);
editor.apply();
}
}

18
app/src/main/java/com/gmeremit/online/gmeremittance_native/base/PrivilegedGatewayInterface.java

@ -58,4 +58,22 @@ public interface PrivilegedGatewayInterface extends BaseGatewayInterface {
* This update will trigger broadcast to all observer
*/
void updateUserInfoInBatch(UserInfoModelV2 data);
/**
* Data related to biometric
*/
void persistUserId(String encrypted);
void persistUserPwd(String encrypted);
boolean isFingerPrintAuthEnabled();
String getPersistedUserId();
String getPersistedUserPwd();
void turnOffFingerprintAuth(boolean action);
void flushBiometricData();
}

9
app/src/main/java/com/gmeremit/online/gmeremittance_native/changepasswordV2/gateway/ChangePasswordV2Gateway.java

@ -31,13 +31,4 @@ public class ChangePasswordV2Gateway extends PrivilegedGateway implements Change
}
@Override
public void persistUserPwd(String encrypted) {
GmeApplication.getStorage().edit().putString(PrefKeys.APP_USER_SECRET_KEY,encrypted).apply();
}
@Override
public void turnOffFingerprintAuth(boolean action) {
GmeApplication.getStorage().edit().putBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED,!action).apply();
}
}

5
app/src/main/java/com/gmeremit/online/gmeremittance_native/changepasswordV2/presenter/ChangePasswordV2Presenter.java

@ -156,7 +156,7 @@ public class ChangePasswordV2Presenter extends BasePresenter implements ChangePa
}
private void encryptPassword(String newPassword, String pwdChangeMessage) {
Observable.zip(SecurityUtils.encryptSecret(view.getContext(), newPassword).subscribeOn(Schedulers.io()).onErrorReturn(error -> null), Observable.just(pwdChangeMessage), BiometricPwdParams::new)
Observable.zip(SecurityUtils.encryptSecret(view.getContext(), newPassword).subscribeOn(Schedulers.io()), Observable.just(pwdChangeMessage), BiometricPwdParams::new)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiometricEncrypterObserver());
@ -243,8 +243,7 @@ public class ChangePasswordV2Presenter extends BasePresenter implements ChangePa
@Override
public void onError(Throwable e) {
gateway.persistUserPwd(null);
gateway.turnOffFingerprintAuth(true);
gateway.flushBiometricData();
}
@Override

31
app/src/main/java/com/gmeremit/online/gmeremittance_native/loginV2/gateway/LoginV2Gateway.java

@ -82,36 +82,5 @@ public class LoginV2Gateway extends PrivilegedGateway implements LoginV2Interact
});
}
@Override
public void persistUserId(String encrypted) {
GmeApplication.getStorage().edit().putString(PrefKeys.APP_USER_ID_SECRET_KEY,encrypted).apply();
}
@Override
public void persistUserPwd(String encrypted) {
GmeApplication.getStorage().edit().putString(PrefKeys.APP_USER_SECRET_KEY,encrypted).apply();
}
@Override
public boolean isFingerPrintAuthEnabled() {
return GmeApplication.getStorage().getBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED,false);
}
@Override
public String getPersistedUserId() {
return GmeApplication.getStorage().getString(PrefKeys.APP_USER_ID_SECRET_KEY,null);
}
@Override
public String getPersistedUserPwd() {
return GmeApplication.getStorage().getString(PrefKeys.APP_USER_SECRET_KEY,null);
}
@Override
public void turnOffFingerprintAuth(boolean action) {
GmeApplication.getStorage().edit().putBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED,!action).apply();
}
}

9
app/src/main/java/com/gmeremit/online/gmeremittance_native/loginV2/presenter/LoginV2InteractorInterface.java

@ -16,15 +16,6 @@ public interface LoginV2InteractorInterface extends BaseInteractorInterface {
Observable<Boolean> saveUserInfo(LoginModelV2 userRelatedData);
void persistUserId(String encrypted);
void persistUserPwd(String encrypted);
boolean isFingerPrintAuthEnabled();
String getPersistedUserId();
String getPersistedUserPwd();
void turnOffFingerprintAuth(boolean action);
}
}

9
app/src/main/java/com/gmeremit/online/gmeremittance_native/loginV2/presenter/LoginV2Presenter.java

@ -1,5 +1,7 @@
package com.gmeremit.online.gmeremittance_native.loginV2.presenter;
import android.os.Build;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.util.Log;
import com.gmeremit.online.gmeremittance_native.GmeApplication;
@ -119,7 +121,10 @@ public class LoginV2Presenter extends BasePresenter implements LoginV2PresenterI
.observeOn(AndroidSchedulers.mainThread())
.retryWhen(errors -> errors.flatMap(
error -> {
if (error instanceof SecurityUtils.FailedFingerPrintException || error instanceof SecurityUtils.SensorNotReadyException) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && error instanceof KeyPermanentlyInvalidatedException) {
view.showFingerPrintScanner(false);
gateway.flushBiometricData();
} else if (error instanceof SecurityUtils.FailedFingerPrintException || error instanceof SecurityUtils.SensorNotReadyException) {
view.showToastMessage(error.getMessage());
return Observable.timer(100, TimeUnit.MILLISECONDS);
}
@ -287,6 +292,8 @@ public class LoginV2Presenter extends BasePresenter implements LoginV2PresenterI
@Override
public void onError(Throwable e) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && e instanceof KeyPermanentlyInvalidatedException)
return;
view.showToastMessage(e.getMessage());
}

2
app/src/main/java/com/gmeremit/online/gmeremittance_native/loginV2/presenter/LoginV2PresenterInterface.java

@ -36,5 +36,7 @@ public interface LoginV2PresenterInterface extends BasePresenterInterface {
Context getContext();
void onLoginPerformTask(Runnable task);
void showFingerPrintScanner(boolean b);
}
}

10
app/src/main/java/com/gmeremit/online/gmeremittance_native/loginV2/view/LoginV2Activity.java

@ -165,7 +165,7 @@ public class LoginV2Activity extends BaseActivity implements View.OnClickListene
private void performDefaultAction(Bundle savedInstanceState) {
if (presenter.checkIfBiometricIsAvailable()) {
fingerprintScannerImgView.setVisibility(View.VISIBLE);
showFingerPrintScanner(true);
fingerPrintAVDCompat = AnimatedVectorDrawableCompat.create(this, R.drawable.avd_fingerprint_off_to_on);
}
}
@ -270,6 +270,14 @@ public class LoginV2Activity extends BaseActivity implements View.OnClickListene
morphButtonIntoProgressBar(task);
}
@Override
public void showFingerPrintScanner(boolean action) {
if (action)
fingerprintScannerImgView.setVisibility(View.VISIBLE);
else
fingerprintScannerImgView.setVisibility(View.GONE);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return (isLoadingInProgress || securityKeyboardView.checkIfTouchIntersectKeypadLayout(ev) || super.dispatchTouchEvent(ev));

5
app/src/main/java/com/gmeremit/online/gmeremittance_native/settings/view/FingerPrintAuthPromptDialog.java

@ -8,6 +8,7 @@ import android.graphics.drawable.AnimatedVectorDrawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.support.graphics.drawable.AnimatedVectorDrawableCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
@ -178,6 +179,9 @@ public class FingerPrintAuthPromptDialog extends android.support.v4.app.DialogFr
@Override
public void onError(Throwable e) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && e instanceof KeyPermanentlyInvalidatedException) {
listener.onFingerPrintInvalidatedBySystem();
}
showToastMessage(e.getMessage());
}
@ -191,5 +195,6 @@ public class FingerPrintAuthPromptDialog extends android.support.v4.app.DialogFr
public interface FingerprintAuthListener
{
void onFingerPrintAuthenticated(boolean userAction);
void onFingerPrintInvalidatedBySystem();
}
}

82
app/src/main/java/com/gmeremit/online/gmeremittance_native/settings/view/SettingsView.java

@ -3,6 +3,7 @@ package com.gmeremit.online.gmeremittance_native.settings.view;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v7.widget.SwitchCompat;
import android.view.View;
@ -61,15 +62,18 @@ public class SettingsView extends BaseActivity implements CompoundButton.OnCheck
if (!SecurityUtils.doesAppHasBiometricFeature(this)) {
view_fingerprint.setVisibility(View.GONE);
view_fingerprint_divider.setVisibility(View.GONE);
}
else
{
} else {
checkIfFingerPrintIsEnabled();
}
}
private void checkIfFingerPrintIsEnabled() {
view_fingerprint.setChecked(GmeApplication.getStorage().getBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED,false));
view_fingerprint.setChecked(GmeApplication.getStorage().getBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED, false));
}
private boolean isBiometricDataAvailable() {
SharedPreferences sp = GmeApplication.getStorage();
return sp.getString(PrefKeys.APP_USER_ID_SECRET_KEY, null) != null && sp.getString(PrefKeys.APP_USER_SECRET_KEY, null) != null;
}
@OnClick({R.id.view_change_password, R.id.iv_back, R.id.view_language, R.id.view_fingerprint})
@ -177,33 +181,57 @@ public class SettingsView extends BaseActivity implements CompoundButton.OnCheck
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
switch(buttonView.getId())
{
case R.id.view_fingerprint:
{
switch (buttonView.getId()) {
case R.id.view_fingerprint: {
view_fingerprint.setOnCheckedChangeListener(null);
view_fingerprint.setChecked(!isChecked);
view_fingerprint.setOnCheckedChangeListener(this);
FingerPrintAuthPromptDialog fingerPrintAuthPromptDialog=new FingerPrintAuthPromptDialog();
fingerPrintAuthPromptDialog.setFingerprintAuthListener(isChecked, new FingerPrintAuthPromptDialog.FingerprintAuthListener() {
@Override
public void onFingerPrintAuthenticated(boolean userAction) {
GmeApplication.getStorage().edit().putBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED,userAction).apply();
view_fingerprint.setOnCheckedChangeListener(null);
view_fingerprint.setChecked(userAction);
view_fingerprint.setOnCheckedChangeListener(SettingsView.this);
if(fingerPrintAuthPromptDialog!=null)
fingerPrintAuthPromptDialog.dismiss();
}
});
if(!fingerPrintAuthPromptDialog.isAdded())
fingerPrintAuthPromptDialog.show(getSupportFragmentManager(), "FingerPrintScannerPromptDialog");
//TODO check if biometric data are available
if (isBiometricDataAvailable()) {
FingerPrintAuthPromptDialog fingerPrintAuthPromptDialog = new FingerPrintAuthPromptDialog();
fingerPrintAuthPromptDialog.setFingerprintAuthListener(isChecked, new FingerPrintAuthPromptDialog.FingerprintAuthListener() {
@Override
public void onFingerPrintAuthenticated(boolean userAction) {
GmeApplication.getStorage().edit().putBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED, userAction).apply();
view_fingerprint.setOnCheckedChangeListener(null);
view_fingerprint.setChecked(userAction);
view_fingerprint.setOnCheckedChangeListener(SettingsView.this);
if (fingerPrintAuthPromptDialog != null)
fingerPrintAuthPromptDialog.dismiss();
}
@Override
public void onFingerPrintInvalidatedBySystem() {
view_fingerprint.setOnCheckedChangeListener(null);
view_fingerprint.setChecked(false);
view_fingerprint.setOnCheckedChangeListener(SettingsView.this);
if (fingerPrintAuthPromptDialog != null)
fingerPrintAuthPromptDialog.dismiss();
new Handler().postDelayed(()->{
GmeApplication.getStorage().edit().clear().apply();
showPopUpMessage(getString(R.string.fingerprint_changed_externally), CustomAlertDialog.AlertType.ALERT,
alert -> {
logout();
});
},200);
}
});
if (!fingerPrintAuthPromptDialog.isAdded())
fingerPrintAuthPromptDialog.show(getSupportFragmentManager(), "FingerPrintScannerPromptDialog");
} else {
showPopUpMessage(getString(R.string.fingerprint_changed_externally), CustomAlertDialog.AlertType.ALERT,
alert -> {
GmeApplication.getStorage().edit().clear().apply();
logout();
});
}
}
}

24
app/src/main/java/com/gmeremit/online/gmeremittance_native/transactionpasspromt/gateway/TransactionPasswordPromptV2Gateway.java

@ -31,28 +31,4 @@ public class TransactionPasswordPromptV2Gateway extends PrivilegedGateway implem
return HttpClientV2.getInstance().requestOTPForSendMoney(auth,jsonObject);
}
@Override
public boolean isFingerPrintEnabled() {
return GmeApplication.getStorage().getBoolean(APP_FINGER_PRINT_ENABLED,false);
}
@Override
public String getStoredSecretKey() {
return GmeApplication.getStorage().getString(APP_USER_SECRET_KEY,null);
}
@Override
public boolean isFingerPrintAuthEnabled() {
return GmeApplication.getStorage().getBoolean(PrefKeys.APP_FINGER_PRINT_ENABLED,false);
}
@Override
public String getPersistedUserId() {
return GmeApplication.getStorage().getString(PrefKeys.APP_USER_ID_SECRET_KEY,null);
}
@Override
public String getPersistedUserPwd() {
return GmeApplication.getStorage().getString(PrefKeys.APP_USER_SECRET_KEY,null);
}
}

9
app/src/main/java/com/gmeremit/online/gmeremittance_native/transactionpasspromt/presenter/TransactionPasswordPromptV2InteractorInterface.java

@ -12,14 +12,5 @@ public interface TransactionPasswordPromptV2InteractorInterface extends BaseInte
{
Observable<ResponseBody> requestOtp(String auth, String Uid,String amount,String kftc);
boolean isFingerPrintEnabled();
String getStoredSecretKey();
boolean isFingerPrintAuthEnabled();
String getPersistedUserId();
String getPersistedUserPwd();
}
}

106
app/src/main/java/com/gmeremit/online/gmeremittance_native/transactionpasspromt/presenter/TransactionPasswordPromptV2Presenter.java

@ -1,20 +1,31 @@
package com.gmeremit.online.gmeremittance_native.transactionpasspromt.presenter;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import com.gmeremit.online.gmeremittance_native.R;
import com.gmeremit.online.gmeremittance_native.base.BasePresenter;
import com.gmeremit.online.gmeremittance_native.customwidgets.CustomAlertDialog;
import com.gmeremit.online.gmeremittance_native.transactionpasspromt.gateway.TransactionPasswordPromptV2Gateway;
import com.gmeremit.online.gmeremittance_native.transactionpasspromt.view.TransactionPasswordPromptActivity;
import com.gmeremit.online.gmeremittance_native.utils.Constants;
import com.gmeremit.online.gmeremittance_native.utils.https.GenericApiObserverResponseV2;
import com.gmeremit.online.gmeremittance_native.utils.https.GenericResponseDataModel;
import com.gmeremit.online.gmeremittance_native.utils.https.MessageResponseDataModel;
import com.gmeremit.online.gmeremittance_native.utils.security.SecurityUtils;
import com.google.gson.reflect.TypeToken;
import com.mtramin.rxfingerprint.data.FingerprintDecryptionResult;
import java.lang.reflect.Type;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.schedulers.Schedulers;
public class TransactionPasswordPromptV2Presenter extends BasePresenter implements TransactionPasswordPromptV2PresenterInterface, TransactionPasswordPromptV2InteractorInterface {
@ -22,20 +33,25 @@ public class TransactionPasswordPromptV2Presenter extends BasePresenter implemen
private final TransactionPasswordPromptV2PresenterInterface.TransactionPasswordPromptV2ContractInterface view;
private final TransactionPasswordPromptV2InteractorInterface.TransactionPasswordPromptV2GatewayInterface gateway;
private final CompositeDisposable compositeDisposable;
private final String selectedPaymentType;
private long updateCountdownValue;
private String selectedAmount;
private String selectedKftcId;
private Disposable fingerPrintScanningSubscription;
private boolean isKeyPermanentlyInvalidated = false;
public TransactionPasswordPromptV2Presenter(TransactionPasswordPromptV2PresenterInterface.TransactionPasswordPromptV2ContractInterface view) {
public TransactionPasswordPromptV2Presenter(TransactionPasswordPromptV2PresenterInterface.TransactionPasswordPromptV2ContractInterface view, String paymentType) {
this.view = view;
this.gateway = new TransactionPasswordPromptV2Gateway(this);
this.compositeDisposable = new CompositeDisposable();
this.updateCountdownValue = -1;
this.selectedKftcId = "";
this.selectedAmount = "";
this.selectedPaymentType = paymentType;
}
@Override
public void getOtp() {
if (updateCountdownValue == -1) {
@ -80,14 +96,74 @@ public class TransactionPasswordPromptV2Presenter extends BasePresenter implemen
@Override
public boolean checkIfUserHasEnabledBiometricAuth() {
return SecurityUtils.doesAppHasBiometricFeature(view.getContext())&&gateway.isFingerPrintAuthEnabled()&&gateway.getPersistedUserId()!=null&&gateway.getPersistedUserPwd()!=null;
return SecurityUtils.doesAppHasBiometricFeature(view.getContext()) && gateway.isFingerPrintAuthEnabled() && gateway.getPersistedUserId() != null && gateway.getPersistedUserPwd() != null;
}
@Override
public String getSecretKey() {
return gateway.getStoredSecretKey();
public void startObservingFingerPrintIfRequired(boolean action) {
if (!checkIfUserHasEnabledBiometricAuth())
return;
if (!action) {
if (fingerPrintScanningSubscription != null && !fingerPrintScanningSubscription.isDisposed())
fingerPrintScanningSubscription.dispose();
view.animateFingerPrintAppearAnimationIfRequired(false);
} else {
fingerPrintScanningSubscription = SecurityUtils.decryptSecret(view.getContext(), gateway.getPersistedUserPwd())
.subscribeOn(Schedulers.io())
.doOnSubscribe(subs -> view.animateFingerPrintAppearAnimationIfRequired(true))
.flatMap(authentication -> {
switch (authentication.getResult()) {
case FAILED:
return io.reactivex.Observable.error(new SecurityUtils.FailedFingerPrintException(getStringfromStringId(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 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && error instanceof KeyPermanentlyInvalidatedException) {
view.addFingerprintIcon(false);
gateway.flushBiometricData();
} else if (error instanceof SecurityUtils.FailedFingerPrintException || error instanceof SecurityUtils.SensorNotReadyException) {
view.showToastMessage(error.getMessage());
return Observable.timer(100, TimeUnit.MILLISECONDS);
}
return Observable.error(error);
}
))
.subscribeWith(new FingerPrintScannerObserver());
}
if (fingerPrintScanningSubscription != null)
compositeDisposable.add(fingerPrintScanningSubscription);
}
@Override
public boolean checkIfRequiredOTPScreen() {
return selectedPaymentType.equalsIgnoreCase("autodebit");
}
@Override
public void verifyTxnType() {
if (checkIfRequiredOTPScreen()) {
view.setupAutoDebitTxnPasswordPromptView();
view.addFingerprintIcon(false);
} else {
view.setupWalletTxnPasswordPromptView();
if (checkIfUserHasEnabledBiometricAuth())
view.addFingerprintIcon(true);
else view.addFingerprintIcon(false);
}
}
@ -130,4 +206,26 @@ public class TransactionPasswordPromptV2Presenter extends BasePresenter implemen
view.showPopUpMessage(message, CustomAlertDialog.AlertType.ALERT, alertType -> view.logout());
}
}
class FingerPrintScannerObserver extends DisposableObserver<FingerprintDecryptionResult> {
@Override
public void onNext(FingerprintDecryptionResult fingerprintAuthenticationResult) {
view.onBiometricAuthSuccess(fingerprintAuthenticationResult.getDecrypted());
}
@Override
public void onError(Throwable e) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && e instanceof KeyPermanentlyInvalidatedException) {
return;
}
view.showToastMessage(e.getMessage());
}
@Override
public void onComplete() {
}
}
}

12
app/src/main/java/com/gmeremit/online/gmeremittance_native/transactionpasspromt/presenter/TransactionPasswordPromptV2PresenterInterface.java

@ -18,8 +18,12 @@ public interface TransactionPasswordPromptV2PresenterInterface extends BasePrese
boolean checkIfUserHasEnabledBiometricAuth();
String getSecretKey();
void startObservingFingerPrintIfRequired(boolean action);
boolean checkIfRequiredOTPScreen();
void verifyTxnType();
interface TransactionPasswordPromptV2ContractInterface extends BaseContractInterface {
@ -28,7 +32,13 @@ public interface TransactionPasswordPromptV2PresenterInterface extends BasePrese
Context getContext();
void onBiometricAuthSuccess(String decPassword);
void animateFingerPrintAppearAnimationIfRequired(boolean action);
void setupAutoDebitTxnPasswordPromptView();
void setupWalletTxnPasswordPromptView();
void addFingerprintIcon(boolean action);
}
}

182
app/src/main/java/com/gmeremit/online/gmeremittance_native/transactionpasspromt/view/TransactionPasswordPromptActivity.java

@ -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() {
}
}
}

1
app/src/main/res/values/strings.xml

@ -469,6 +469,7 @@
<string name="enter_bank_ac_no">Enter your bank account number</string>
<string name="select_language">Select language</string>
<string name="touch_fingerprint_text">Please place your finger on the fingerprint sensor to continue.</string>
<string name="fingerprint_changed_externally">Your fingerprint has been changed. Please login again to continue.</string>
</resources>
Loading…
Cancel
Save