@ -59,6 +59,10 @@ public class AuthActivity extends AegisActivity {
private BiometricSlot _bioSlot ;
private BiometricSlot _bioSlot ;
private BiometricPrompt _bioPrompt ;
private BiometricPrompt _bioPrompt ;
// the first time this activity is resumed after creation, it's possible to inhibit showing the
// biometric prompt by setting 'inhibitBioPrompt' to false through the intent
private boolean _inhibitBioPrompt ;
private Preferences _prefs ;
private Preferences _prefs ;
private boolean _stateless ;
private boolean _stateless ;
@ -80,6 +84,7 @@ public class AuthActivity extends AegisActivity {
} ) ;
} ) ;
Intent intent = getIntent ( ) ;
Intent intent = getIntent ( ) ;
_inhibitBioPrompt = savedInstanceState = = null ? ! intent . getBooleanExtra ( "_inhibitBioPrompt" , true ) : savedInstanceState . getBoolean ( "_inhibitBioPrompt" ) ;
_cancelAction = ( CancelAction ) intent . getSerializableExtra ( "cancelAction" ) ;
_cancelAction = ( CancelAction ) intent . getSerializableExtra ( "cancelAction" ) ;
_slots = ( SlotList ) intent . getSerializableExtra ( "slots" ) ;
_slots = ( SlotList ) intent . getSerializableExtra ( "slots" ) ;
_stateless = _slots ! = null ;
_stateless = _slots ! = null ;
@ -145,10 +150,12 @@ public class AuthActivity extends AegisActivity {
biometricsButton . setOnClickListener ( v - > {
biometricsButton . setOnClickListener ( v - > {
showBiometricPrompt ( ) ;
showBiometricPrompt ( ) ;
} ) ;
} ) ;
}
if ( _bioKey ! = null ) {
@Override
showBiometricPrompt ( ) ;
protected void onSaveInstanceState ( @NonNull Bundle outState ) {
}
super . onSaveInstanceState ( outState ) ;
outState . putBoolean ( "inhibitBioPrompt" , _inhibitBioPrompt ) ;
}
}
@Override
@Override
@ -203,6 +210,22 @@ public class AuthActivity extends AegisActivity {
if ( _bioKey = = null | | _prefs . isPasswordReminderNeeded ( ) ) {
if ( _bioKey = = null | | _prefs . isPasswordReminderNeeded ( ) ) {
focusPasswordField ( ) ;
focusPasswordField ( ) ;
}
}
if ( _bioKey ! = null & & _bioPrompt = = null & & ! _inhibitBioPrompt ) {
_bioPrompt = showBiometricPrompt ( ) ;
}
_inhibitBioPrompt = false ;
}
@Override
public void onPause ( ) {
if ( ! isChangingConfigurations ( ) & & _bioPrompt ! = null ) {
_bioPrompt . cancelAuthentication ( ) ;
_bioPrompt = null ;
}
super . onPause ( ) ;
}
}
@Override
@Override
@ -229,25 +252,26 @@ public class AuthActivity extends AegisActivity {
_textPassword . postDelayed ( popup : : dismiss , 5000 ) ;
_textPassword . postDelayed ( popup : : dismiss , 5000 ) ;
}
}
public void showBiometricPrompt ( ) {
public BiometricPrompt showBiometricPrompt ( ) {
Cipher cipher ;
Cipher cipher ;
try {
try {
cipher = _bioSlot . createDecryptCipher ( _bioKey ) ;
cipher = _bioSlot . createDecryptCipher ( _bioKey ) ;
} catch ( SlotException e ) {
} catch ( SlotException e ) {
e . printStackTrace ( ) ;
e . printStackTrace ( ) ;
Dialogs . showErrorDialog ( this , R . string . biometric_init_error , e ) ;
Dialogs . showErrorDialog ( this , R . string . biometric_init_error , e ) ;
return ;
return null ;
}
}
BiometricPrompt . CryptoObject cryptoObj = new BiometricPrompt . CryptoObject ( cipher ) ;
BiometricPrompt . CryptoObject cryptoObj = new BiometricPrompt . CryptoObject ( cipher ) ;
_bioP rompt = new BiometricPrompt ( this , new UiThreadExecutor ( ) , new BiometricPromptListener ( ) ) ;
BiometricPrompt p rompt = new BiometricPrompt ( this , new UiThreadExecutor ( ) , new BiometricPromptListener ( ) ) ;
BiometricPrompt . PromptInfo info = new BiometricPrompt . PromptInfo . Builder ( )
BiometricPrompt . PromptInfo info = new BiometricPrompt . PromptInfo . Builder ( )
. setTitle ( getString ( R . string . authentication ) )
. setTitle ( getString ( R . string . authentication ) )
. setNegativeButtonText ( getString ( android . R . string . cancel ) )
. setNegativeButtonText ( getString ( android . R . string . cancel ) )
. setConfirmationRequired ( false )
. setConfirmationRequired ( false )
. build ( ) ;
. build ( ) ;
_bioPrompt . authenticate ( info , cryptoObj ) ;
prompt . authenticate ( info , cryptoObj ) ;
return prompt ;
}
}
private void finish ( MasterKey key , boolean isSlotRepaired ) {
private void finish ( MasterKey key , boolean isSlotRepaired ) {
@ -306,6 +330,8 @@ public class AuthActivity extends AegisActivity {
@Override
@Override
public void onAuthenticationError ( int errorCode , @NonNull CharSequence errString ) {
public void onAuthenticationError ( int errorCode , @NonNull CharSequence errString ) {
super . onAuthenticationError ( errorCode , errString ) ;
super . onAuthenticationError ( errorCode , errString ) ;
_bioPrompt = null ;
if ( ! BiometricsHelper . isCanceled ( errorCode ) ) {
if ( ! BiometricsHelper . isCanceled ( errorCode ) ) {
Toast . makeText ( AuthActivity . this , errString , Toast . LENGTH_LONG ) . show ( ) ;
Toast . makeText ( AuthActivity . this , errString , Toast . LENGTH_LONG ) . show ( ) ;
}
}
@ -314,6 +340,7 @@ public class AuthActivity extends AegisActivity {
@Override
@Override
public void onAuthenticationSucceeded ( @NonNull BiometricPrompt . AuthenticationResult result ) {
public void onAuthenticationSucceeded ( @NonNull BiometricPrompt . AuthenticationResult result ) {
super . onAuthenticationSucceeded ( result ) ;
super . onAuthenticationSucceeded ( result ) ;
_bioPrompt = null ;
MasterKey key ;
MasterKey key ;
BiometricSlot slot = _slots . find ( BiometricSlot . class ) ;
BiometricSlot slot = _slots . find ( BiometricSlot . class ) ;