@@ -23,15 +23,14 @@ namespace BiometryService;
2323/// <summary>
2424/// Implementation of the <see cref="IBiometryService" /> for Android.
2525/// </summary>
26- public sealed partial class BiometryService : IBiometryService
26+ public sealed class BiometryService : BaseBiometryService
2727{
2828 private const string ANDROID_KEYSTORE = "AndroidKeyStore" ; // Android constant, cannot be changed.
2929 private const string CIPHER_NAME = "AES/CBC/PKCS7Padding" ;
3030 private const string PREFERENCE_NAME = "BiometricPreferences" ;
3131
3232 private readonly FragmentActivity _activity ;
3333 private readonly Func < BiometricPrompt . PromptInfo > _promptInfoBuilder ;
34- private readonly ILogger _logger ;
3534 private readonly Context _applicationContext ;
3635 private readonly BiometricManager _biometricManager ;
3736 private readonly KeyStore _keyStore ;
@@ -44,11 +43,14 @@ public sealed partial class BiometryService : IBiometryService
4443 /// <param name="fragmentActivity"><see cref="FragmentActivity"/>.</param>
4544 /// <param name="promptInfoBuilder">Biometry configuration.</param>
4645 /// <param name="loggerFactory"><see cref="ILoggerFactory"/>.</param>
47- public BiometryService ( FragmentActivity fragmentActivity , Func < BiometricPrompt . PromptInfo > promptInfoBuilder , ILoggerFactory loggerFactory = null )
46+ public BiometryService (
47+ FragmentActivity fragmentActivity ,
48+ Func < BiometricPrompt . PromptInfo > promptInfoBuilder ,
49+ ILoggerFactory loggerFactory = null
50+ ) : base ( loggerFactory )
4851 {
4952 _activity = fragmentActivity ?? throw new ArgumentNullException ( nameof ( fragmentActivity ) ) ;
5053 _promptInfoBuilder = promptInfoBuilder ?? throw new ArgumentNullException ( nameof ( promptInfoBuilder ) ) ;
51- _logger = loggerFactory ? . CreateLogger < IBiometryService > ( ) ?? NullLogger < IBiometryService > . Instance ;
5254
5355 _applicationContext = Application . Context ;
5456 _biometricManager = BiometricManager . From ( _applicationContext ) ;
@@ -58,7 +60,7 @@ public BiometryService(FragmentActivity fragmentActivity, Func<BiometricPrompt.P
5860 }
5961
6062 /// <inheritdoc/>
61- public Task < BiometryCapabilities > GetCapabilities ( CancellationToken ct )
63+ public override Task < BiometryCapabilities > GetCapabilities ( CancellationToken ct )
6264 {
6365 var biometryType = BiometryType . None ;
6466
@@ -79,17 +81,17 @@ public Task<BiometryCapabilities> GetCapabilities(CancellationToken ct)
7981 }
8082
8183 /// <inheritdoc/>
82- public async Task ScanBiometry ( CancellationToken ct )
84+ public override async Task ScanBiometry ( CancellationToken ct )
8385 {
8486 await AuthenticateBiometry ( ct ) ;
8587 }
8688
8789 /// <inheritdoc/>
88- public async Task Encrypt ( CancellationToken ct , string keyName , string value )
90+ public override async Task Encrypt ( CancellationToken ct , string keyName , string value )
8991 {
90- if ( _logger . IsEnabled ( LogLevel . Debug ) )
92+ if ( Logger . IsEnabled ( LogLevel . Debug ) )
9193 {
92- _logger . LogDebug ( $ "Encrypting the fingerprint for the key '{ keyName } '.") ;
94+ Logger . LogDebug ( $ "Encrypting the fingerprint for the key '{ keyName } '.") ;
9395 }
9496
9597 await ValidateBiometryCapabilities ( ct ) ;
@@ -104,9 +106,9 @@ public async Task Encrypt(CancellationToken ct, string keyName, string value)
104106 iv . CopyTo ( bytes , 0 ) ;
105107 encryptedData . CopyTo ( bytes , iv . Length ) ;
106108
107- if ( _logger . IsEnabled ( LogLevel . Information ) )
109+ if ( Logger . IsEnabled ( LogLevel . Information ) )
108110 {
109- _logger . LogInformation ( $ "Succcessfully encrypted the fingerprint for the key'{ keyName } '.") ;
111+ Logger . LogInformation ( $ "Succcessfully encrypted the fingerprint for the key'{ keyName } '.") ;
110112 }
111113
112114 var encodedData = Base64 . EncodeToString ( bytes , Base64Flags . NoWrap ) ;
@@ -115,11 +117,11 @@ public async Task Encrypt(CancellationToken ct, string keyName, string value)
115117 }
116118
117119 /// <inheritdoc/>
118- public async Task < string > Decrypt ( CancellationToken ct , string keyName )
120+ public override async Task < string > Decrypt ( CancellationToken ct , string keyName )
119121 {
120- if ( _logger . IsEnabled ( LogLevel . Debug ) )
122+ if ( Logger . IsEnabled ( LogLevel . Debug ) )
121123 {
122- _logger . LogDebug ( $ "Decrypting the fingerprint for the key '{ keyName } '.") ;
124+ Logger . LogDebug ( $ "Decrypting the fingerprint for the key '{ keyName } '.") ;
123125 }
124126
125127 await ValidateBiometryCapabilities ( ct ) ;
@@ -156,26 +158,42 @@ public async Task<string> Decrypt(CancellationToken ct, string keyName)
156158 var result = await AuthenticateBiometry ( ct , crypto ) ;
157159 var decryptedData = result . CryptoObject . Cipher . DoFinal ( buffer ) ;
158160
159- if ( _logger . IsEnabled ( LogLevel . Information ) )
161+ if ( Logger . IsEnabled ( LogLevel . Information ) )
160162 {
161- _logger . LogInformation ( $ "Succcessfully decrypted the fingerprint for the key '{ keyName } '.") ;
163+ Logger . LogInformation ( $ "Succcessfully decrypted the fingerprint for the key '{ keyName } '.") ;
162164 }
163165
164166 return Encoding . ASCII . GetString ( decryptedData ) ;
165167 }
166168
167169 /// <inheritdoc/>
168- public void Remove ( string keyName )
170+ public override void Remove ( string keyName )
169171 {
170- var sharedpref = _applicationContext . GetSharedPreferences ( PREFERENCE_NAME , FileCreationMode . Private ) ;
171- sharedpref . Edit ( ) . Remove ( keyName ) . Apply ( ) ;
172+ try
173+ {
174+ var sharedpref = _applicationContext . GetSharedPreferences ( PREFERENCE_NAME , FileCreationMode . Private ) ;
175+ sharedpref . Edit ( ) . Remove ( keyName ) . Apply ( ) ;
176+
177+ if ( Logger . IsEnabled ( LogLevel . Debug ) )
178+ {
179+ Logger . LogDebug ( "The key '{keyName}' has been successfully removed." , keyName ) ;
180+ }
181+ }
182+ catch ( System . Exception )
183+ {
184+ if ( Logger . IsEnabled ( LogLevel . Debug ) )
185+ {
186+ Logger . LogDebug ( "The key '{keyName}' has not been successfully removed." , keyName ) ;
187+ }
188+ throw new BiometryException ( BiometryExceptionReason . Failed , $ "Something went wrong while removing the key '{ keyName } '.") ;
189+ }
172190 }
173191
174192 private async Task < BiometricPrompt . AuthenticationResult > AuthenticateBiometry ( CancellationToken ct , BiometricPrompt . CryptoObject crypto = null )
175193 {
176- if ( _logger . IsEnabled ( LogLevel . Debug ) )
194+ if ( Logger . IsEnabled ( LogLevel . Debug ) )
177195 {
178- _logger . LogDebug ( $ "Start authenticating the user biometry.") ;
196+ Logger . LogDebug ( $ "Start authenticating the user biometry.") ;
179197 }
180198
181199 // TODO: Refactor this. Why are we doing a version check? Could we juste use the parameter used by the user isntead of BiometricManager.Authenticators.BiometricStrong?
@@ -194,9 +212,9 @@ public void Remove(string keyName)
194212 return await PromptBiometryAuthentication ( ct , crypto ) ;
195213 }
196214
197- if ( _logger . IsEnabled ( LogLevel . Error ) )
215+ if ( Logger . IsEnabled ( LogLevel . Error ) )
198216 {
199- _logger . LogError ( $ "The device cannot authenticate with biometry.") ;
217+ Logger . LogError ( $ "The device cannot authenticate with biometry.") ;
200218 }
201219
202220 var reason = BiometryExceptionReason . Failed ;
@@ -228,7 +246,7 @@ public void Remove(string keyName)
228246 _authenticationCompletionSource = new TaskCompletionSource < BiometricPrompt . AuthenticationResult > ( ) ;
229247
230248 // Prepare and show UI.
231- var callback = new AuthenticationCallback ( _authenticationCompletionSource , _logger ) ;
249+ var callback = new AuthenticationCallback ( _authenticationCompletionSource , Logger ) ;
232250 var executor = ContextCompat . GetMainExecutor ( _applicationContext ) ;
233251 var biometricPrompt = new BiometricPrompt ( _activity , executor , callback ) ;
234252
@@ -260,9 +278,9 @@ public void Remove(string keyName)
260278
261279 if ( authenticationTask . IsCompletedSuccessfully )
262280 {
263- if ( _logger . IsEnabled ( LogLevel . Information ) )
281+ if ( Logger . IsEnabled ( LogLevel . Information ) )
264282 {
265- _logger . LogInformation ( $ "Successfully authenticated and processed the biometric).") ;
283+ Logger . LogInformation ( $ "Successfully authenticated and processed the biometric).") ;
266284 }
267285
268286 return authenticationTask . Result ;
@@ -287,9 +305,9 @@ private BiometricPrompt.CryptoObject CreateCryptoObject(string keyName)
287305 _keyStore . DeleteEntry ( keyName ) ;
288306 }
289307
290- if ( _logger . IsEnabled ( LogLevel . Debug ) )
308+ if ( Logger . IsEnabled ( LogLevel . Debug ) )
291309 {
292- _logger . LogDebug ( $ "Generating a symmetric pair (key name: '{ keyName } ').") ;
310+ Logger . LogDebug ( $ "Generating a symmetric pair (key name: '{ keyName } ').") ;
293311 }
294312
295313 var keygen = KeyGenerator . GetInstance ( KeyProperties . KeyAlgorithmAes , ANDROID_KEYSTORE ) ;
@@ -304,9 +322,9 @@ private BiometricPrompt.CryptoObject CreateCryptoObject(string keyName)
304322
305323 keygen . GenerateKey ( ) ;
306324
307- if ( _logger . IsEnabled ( LogLevel . Information ) )
325+ if ( Logger . IsEnabled ( LogLevel . Information ) )
308326 {
309- _logger . LogInformation ( $ "Successfully generated a symmetric pair (key name: '{ keyName } ').") ;
327+ Logger . LogInformation ( $ "Successfully generated a symmetric pair (key name: '{ keyName } ').") ;
310328 }
311329
312330 cipher . Init ( CipherMode . EncryptMode , _keyStore . GetKey ( keyName , null ) ) ;
@@ -328,26 +346,26 @@ private BiometricPrompt.CryptoObject GetCryptoObject(string keyName, byte[] iv =
328346 }
329347 catch ( KeyPermanentlyInvalidatedException )
330348 {
331- if ( _logger . IsEnabled ( LogLevel . Error ) )
349+ if ( Logger . IsEnabled ( LogLevel . Error ) )
332350 {
333- _logger . LogError ( $ "Key '{ keyName } ' has been permanently invalidated.") ;
351+ Logger . LogError ( $ "Key '{ keyName } ' has been permanently invalidated.") ;
334352 }
335353
336354 _keyStore . DeleteEntry ( keyName ) ;
337355
338- if ( _logger . IsEnabled ( LogLevel . Information ) )
356+ if ( Logger . IsEnabled ( LogLevel . Information ) )
339357 {
340- _logger . LogInformation ( $ "Permanently invalidated key '{ keyName } ' has been removed successfully.") ;
358+ Logger . LogInformation ( $ "Permanently invalidated key '{ keyName } ' has been removed successfully.") ;
341359 }
342360
343361 throw new BiometryException ( BiometryExceptionReason . KeyInvalidated , "Something went wrong while generating the CryptoObject used to decrypt." ) ;
344362 }
345363 }
346364 else
347365 {
348- if ( _logger . IsEnabled ( LogLevel . Error ) )
366+ if ( Logger . IsEnabled ( LogLevel . Error ) )
349367 {
350- _logger . LogError ( $ "Key '{ keyName } ' not found.") ;
368+ Logger . LogError ( $ "Key '{ keyName } ' not found.") ;
351369 }
352370 throw new BiometryException ( BiometryExceptionReason . KeyInvalidated , $ "Key '{ keyName } ' not found.") ;
353371 }
@@ -356,19 +374,19 @@ private BiometricPrompt.CryptoObject GetCryptoObject(string keyName, byte[] iv =
356374 private class AuthenticationCallback : BiometricPrompt . AuthenticationCallback
357375 {
358376 private readonly TaskCompletionSource < BiometricPrompt . AuthenticationResult > _tcs ;
359- private readonly ILogger _logger ;
377+ private readonly ILogger Logger ;
360378
361379 public AuthenticationCallback ( TaskCompletionSource < BiometricPrompt . AuthenticationResult > tcs , ILogger logger )
362380 {
363381 _tcs = tcs ;
364- _logger = logger ;
382+ Logger = logger ;
365383 }
366384
367385 public override void OnAuthenticationSucceeded ( BiometricPrompt . AuthenticationResult result )
368386 {
369- if ( _logger . IsEnabled ( LogLevel . Information ) )
387+ if ( Logger . IsEnabled ( LogLevel . Information ) )
370388 {
371- _logger . LogInformation ( "User attempt to use biometry succeeded." ) ;
389+ Logger . LogInformation ( "User attempt to use biometry succeeded." ) ;
372390 }
373391
374392 _tcs . TrySetResult ( result ) ;
@@ -379,9 +397,9 @@ public override void OnAuthenticationFailed()
379397 // This methods is called after an attempt to use biometry.
380398 // It does not means that it will close the prompt yet.
381399
382- if ( _logger . IsEnabled ( LogLevel . Warning ) )
400+ if ( Logger . IsEnabled ( LogLevel . Warning ) )
383401 {
384- _logger . LogWarning ( "User attempt to use biometry failed." ) ;
402+ Logger . LogWarning ( "User attempt to use biometry failed." ) ;
385403 }
386404 }
387405
0 commit comments