From c1d67ee5905db01ed6699746f25248114d11d61e Mon Sep 17 00:00:00 2001 From: Piyush7034 <47858366+Piyush7034@users.noreply.github.com> Date: Wed, 10 Apr 2024 21:04:58 +0530 Subject: [PATCH] Onboard operator (#305) * Fixed Changed fetch commit id Signed-off-by: Piyush7034 * Fixed Added try catch for fetching commit ids Signed-off-by: Piyush7034 * Fixed Added the qr code template changes to the acknowledgement template Signed-off-by: G S Prakash Signed-off-by: Piyush7034 * RCF-414 (#247) * Changed fetch commit id Signed-off-by: Piyush7034 * Added try catch for fetching commit ids Signed-off-by: Piyush7034 * Added the qr code template changes to the acknowledgement template Signed-off-by: G S Prakash * Updated the util configuration in the app Signed-off-by: G S Prakash --------- Signed-off-by: Piyush7034 Signed-off-by: G S Prakash Co-authored-by: Piyush7034 Co-authored-by: GSPrakashNaiduCyberpwn <146939767+GSPrakashNaiduCyberpwn@users.noreply.github.com> Signed-off-by: Piyush7034 * Values for all selected langauges added to dto (#248) Signed-off-by: Piyush7034 * Rcf 403 - batch job sync before upload (#246) * transliteration fixes Signed-off-by: Aditya Singh(aditya.singh509) * batch job sync before upload Signed-off-by: Aditya Singh(aditya.singh509) * transliteration from any-any lang Signed-off-by: Aditya Singh(aditya.singh509) --------- Signed-off-by: Aditya Singh(aditya.singh509) Co-authored-by: Aditya Singh(aditya.singh509) Signed-off-by: Piyush7034 * QA platform (#249) * Values for all selected langauges added to dto Signed-off-by: Piyush7034 * change env to qa-platform Signed-off-by: Aditya Singh(aditya.singh509) --------- Signed-off-by: Piyush7034 Signed-off-by: Aditya Singh(aditya.singh509) Co-authored-by: Piyush7034 Co-authored-by: Aditya Singh(aditya.singh509) Signed-off-by: Piyush7034 * Minor bugs (#252) * batch job & error message fix Signed-off-by: Aditya Singh(aditya.singh509) * french transliteration & gender control bug fix Signed-off-by: Aditya Singh(aditya.singh509) --------- Signed-off-by: Aditya Singh(aditya.singh509) Co-authored-by: Aditya Singh(aditya.singh509) Signed-off-by: Piyush7034 * Rcf 358 (#250) * RCF-377 fixed Signed-off-by: aviral-mishra-hunter * Overflow Fix Signed-off-by: aviral-mishra-hunter * Disabled language whose localization file is not available Signed-off-by: Piyush7034 * Small fix Signed-off-by: Piyush7034 * Added locale codes in a constants file Signed-off-by: Piyush7034 * Fixed packet auth page ui Signed-off-by: Piyush7034 * Added more locales to constants Signed-off-by: Piyush7034 * Some changes in auto sync Signed-off-by: Piyush7034 * Fixed auto sync issue Signed-off-by: Piyush7034 * Some changes in save version Signed-off-by: Piyush7034 * Changed save all headers Signed-off-by: Piyush7034 * changed qa-trinity to qa-platform Signed-off-by: Piyush7034 --------- Signed-off-by: aviral-mishra-hunter Signed-off-by: Piyush7034 Co-authored-by: aviral-mishra-hunter Signed-off-by: Piyush7034 * Rcf 415 (#253) * Changed app langauge to be same as mandatory language Signed-off-by: Piyush7034 * Mandatory language as first language in the list Signed-off-by: Piyush7034 --------- Signed-off-by: Piyush7034 * [RCF-407] , [RCF-423] , [RCF-420] (#254) * RCF-407 Resolved Signed-off-by: Aviral Mishra * Initial Commits Signed-off-by: Aviral Mishra * RCF-420 Fixed Signed-off-by: Aviral Mishra * [RCF-407] , [RCF-423] , [RCF-420] Signed-off-by: Aviral Mishra * Some additional changes Signed-off-by: Aviral Mishra --------- Signed-off-by: Aviral Mishra Co-authored-by: Aviral Mishra Signed-off-by: Piyush7034 * RCF-411 (#251) * removed reference id text field mandatory option Signed-off-by: Sachin S P * fixed the alignment issue Signed-off-by: Sachin S P --------- Signed-off-by: Sachin S P Co-authored-by: Sachin S P Signed-off-by: Piyush7034 * Final changes (#255) * Final Changes Signed-off-by: Aviral Mishra * UI Changes Signed-off-by: Aviral Mishra --------- Signed-off-by: Aviral Mishra Co-authored-by: Aviral Mishra Signed-off-by: Piyush7034 * Changed MPL license to MIT license (#256) Signed-off-by: Piyush7034 * audit added before batch job (#257) Signed-off-by: Aditya Singh(aditya.singh509) Co-authored-by: Aditya Singh(aditya.singh509) Signed-off-by: Piyush7034 * Updated the string of Sync Packet Signed-off-by: G S Prakash Signed-off-by: Piyush7034 * Overflow Fix Signed-off-by: Aviral Mishra Signed-off-by: Piyush7034 * RCF-435 Signed-off-by: Aviral Mishra Signed-off-by: Piyush7034 * Minor Change Signed-off-by: Aviral Mishra Signed-off-by: Piyush7034 * RCF-451 Fixed Signed-off-by: Aviral Mishra Signed-off-by: Piyush7034 * Radio Button Fix for Synergy Env Signed-off-by: Aviral Mishra Signed-off-by: Piyush7034 * text alignment for arabic Signed-off-by: Aditya Singh Signed-off-by: Piyush7034 * dynamic alignment of lang text Signed-off-by: Aditya Singh Signed-off-by: Piyush7034 * fixed retrigger multiple time at the T-0 minute Signed-off-by: Aditya Singh Signed-off-by: Piyush7034 * minor changes Signed-off-by: Aditya Singh Signed-off-by: Piyush7034 * default cron expression added Signed-off-by: Aditya Singh Signed-off-by: Piyush7034 * added to constant Signed-off-by: Aditya Singh Signed-off-by: Piyush7034 * RCF-214, RCF-212 and RCF-216 (#261) * added mavel native code Signed-off-by: Sachin S P * changed the new code error Signed-off-by: Sachin S P * fixed the ui break issue Signed-off-by: Sachin S P * document upload screen based on mavel script and application doc type Signed-off-by: Sachin S P * document upload screen validation Signed-off-by: Sachin S P * document upload screen exception proof function Signed-off-by: Sachin S P * exception proof validation Signed-off-by: Sachin S P * made some merge changes Signed-off-by: Sachin S P --------- Signed-off-by: Sachin S P Co-authored-by: Sachin S P Signed-off-by: Piyush7034 * script added in pigeon.sh (#269) Signed-off-by: Sachin S P Co-authored-by: Sachin S P Signed-off-by: Piyush7034 * Revert RCF 216 (#275) * reverted code Signed-off-by: Sachin S P * reverted code Signed-off-by: Sachin S P --------- Signed-off-by: Sachin S P Co-authored-by: Sachin S P Signed-off-by: Piyush7034 * RCF-460: Fixed cacerts sync issue (#271) Signed-off-by: HimajaDhanyamraju2 Signed-off-by: Piyush7034 * Functions added in User Onboard Service from Registrarion Client User Onboard Service Impl Signed-off-by: Aviral Mishra Signed-off-by: Piyush7034 * RCF-35: Added service classes for onboarding Signed-off-by: HimajaDhanyamraju2 Signed-off-by: Piyush7034 * Initial Commit Signed-off-by: Aviral Mishra Signed-off-by: Piyush7034 * First view Added Signed-off-by: Aviral Mishra Signed-off-by: Piyush7034 * Saving data Signed-off-by: Aviral Mishra Signed-off-by: Piyush7034 * UI Complete for Onboarding Operator Signed-off-by: Aviral Mishra Signed-off-by: Piyush7034 * Operation Biometric Capture Backend Complete Signed-off-by: Aviral Mishra Signed-off-by: Piyush7034 * fixed Save Operator Biometrics in progress Signed-off-by: Aviral Mishra Signed-off-by: Piyush7034 * Operator Biometrics Saving In progress Signed-off-by: Aviral Mishra Signed-off-by: Piyush7034 * Threshold added for operator biometrics Signed-off-by: Aviral Mishra Signed-off-by: Piyush7034 * fixed RCF-35: User onboarding changes Signed-off-by: HimajaDhanyamraju2 Signed-off-by: Piyush7034 * RCF-35: Fix in saving biometrics to DB Signed-off-by: HimajaDhanyamraju2 Signed-off-by: Piyush7034 * Fixed Added fix for operator onboard saving Signed-off-by: Piyush7034 * RCF-399 Resolved (#283) Signed-off-by: Aviral Mishra Co-authored-by: Aviral Mishra Signed-off-by: Piyush7034 * Android14 patch (#282) * android 14 alarm permission request added Signed-off-by: Aditya Singh * patch-fixes changes added Signed-off-by: Aditya Singh --------- Signed-off-by: Aditya Singh Co-authored-by: Aditya Singh Signed-off-by: Piyush7034 * MOSIP-31687 (#292) * MOSIP-31687 Signed-off-by: Jayesh Kharode * MOSIP-31687 Signed-off-by: Jayesh Kharode * MOSIP-31687 Signed-off-by: Jayesh Kharode * MOSIP-31687 Signed-off-by: Jayesh Kharode * MOSIP-31687 Signed-off-by: Jayesh Kharode * MOSIP-31687 Signed-off-by: Jayesh Kharode * MOSIP-31687 Signed-off-by: Jayesh Kharode * MOSIP-31687 Signed-off-by: Jayesh Kharode * MOSIP-31687 Signed-off-by: Jayesh Kharode * Delete androidReg-clientTest/.classpath Signed-off-by: jayesh12234 <111957576+jayesh12234@users.noreply.github.com> * Delete androidReg-clientTest/.metadata directory Signed-off-by: jayesh12234 <111957576+jayesh12234@users.noreply.github.com> --------- Signed-off-by: Jayesh Kharode Signed-off-by: jayesh12234 <111957576+jayesh12234@users.noreply.github.com> Co-authored-by: Jayesh Kharode Signed-off-by: Piyush7034 * Added null check conditions (#289) Signed-off-by: Piyush7034 * Changed build branch from feature-flutter to develop (#287) Signed-off-by: Piyush7034 * added event id for scan button and preview doc (#293) Signed-off-by: Sachin S P Co-authored-by: Sachin S P Signed-off-by: Piyush7034 * Added back button functionality on registration screen (#263) * Added back button functionality on registration screen Signed-off-by: Piyush7034 * Changed print ack event id to REG-EVT-012 Signed-off-by: Piyush7034 --------- Signed-off-by: Piyush7034 * Fixed document upload screen based on mavel script (#281) * document upload screen based on mavel script Signed-off-by: Sachin S P * resolve merge conflict Signed-off-by: Sachin S P --------- Signed-off-by: Sachin S P Co-authored-by: Sachin S P Signed-off-by: Piyush7034 * RCF-88 DashBoard UI (#291) * dashboard ui and functionality Signed-off-by: Sachin S P * dashboard ui and functionality Signed-off-by: Sachin S P * handle null check Signed-off-by: Sachin S P * null handle Signed-off-by: Sachin S P * dashboard ui and functionality Signed-off-by: Sachin S P * commented 30 days logic Signed-off-by: Sachin S P * commented 30 days logic Signed-off-by: Sachin S P * changed the logic and name Signed-off-by: Sachin S P --------- Signed-off-by: Sachin S P Co-authored-by: Sachin S P Signed-off-by: Piyush7034 * RCF-88 (#301) * dashboard ui and functionality Signed-off-by: Sachin S P * dashboard ui and functionality Signed-off-by: Sachin S P * handle null check Signed-off-by: Sachin S P * null handle Signed-off-by: Sachin S P * dashboard ui and functionality Signed-off-by: Sachin S P * commented 30 days logic Signed-off-by: Sachin S P * commented 30 days logic Signed-off-by: Sachin S P * changed the logic and name Signed-off-by: Sachin S P * removed some import Signed-off-by: Sachin S P --------- Signed-off-by: Sachin S P Co-authored-by: Sachin S P Signed-off-by: Piyush7034 * RCF-431 Fixed and rescan enabled for operator onboarding Signed-off-by: Aviral Mishra * Pigeon Issue Resolved Signed-off-by: Aviral Mishra * Removed vscode file Signed-off-by: Aviral Mishra * Removed VScode folder Signed-off-by: Aviral Mishra * Fixed timestamp issue Signed-off-by: Piyush7034 * Operator Saving fail scenario added Signed-off-by: Aviral Mishra --------- Signed-off-by: Piyush7034 Signed-off-by: G S Prakash Signed-off-by: Aditya Singh(aditya.singh509) Signed-off-by: aviral-mishra-hunter Signed-off-by: Aviral Mishra Signed-off-by: Sachin S P Signed-off-by: Aditya Singh Signed-off-by: HimajaDhanyamraju2 Signed-off-by: Jayesh Kharode Signed-off-by: jayesh12234 <111957576+jayesh12234@users.noreply.github.com> Co-authored-by: G S Prakash Co-authored-by: G S Prakash Naidu <146939767+GSPrakashNaidu2662@users.noreply.github.com> Co-authored-by: GSPrakashNaiduCyberpwn <146939767+GSPrakashNaiduCyberpwn@users.noreply.github.com> Co-authored-by: Aditya Singh <62157757+developer-aditya@users.noreply.github.com> Co-authored-by: Aditya Singh(aditya.singh509) Co-authored-by: aviral-mishra-hunter Co-authored-by: Aviral Mishra <88927802+aviral-mishra-hunter@users.noreply.github.com> Co-authored-by: Aviral Mishra Co-authored-by: Sachin s p <52343650+SachinPremkumar@users.noreply.github.com> Co-authored-by: Sachin S P Co-authored-by: Aditya Singh Co-authored-by: Himaja Dhanyamraju <43470317+HimajaDhanyamraju2@users.noreply.github.com> Co-authored-by: HimajaDhanyamraju2 Co-authored-by: jayesh12234 <111957576+jayesh12234@users.noreply.github.com> Co-authored-by: Jayesh Kharode --- .gitignore | 2 +- android/app/build.gradle | 2 +- .../registration_client/HostApiModule.java | 5 +- .../api_services/BiometricsDetailsApi.java | 859 +++++-- .../clientmanager/config/AppModule.java | 4 +- .../clientmanager/config/ClientDatabase.java | 6 +- .../clientmanager/config/RoomModule.java | 15 + .../clientmanager/config/SessionManager.java | 1 + .../constant/ClientManagerError.java | 1 + .../constant/RegistrationConstants.java | 11 + .../clientmanager/dao/UserBiometricDao.java | 27 + .../clientmanager/dao/UserDetailDao.java | 3 + .../clientmanager/dto/http/OnboardError.java | 30 + .../dto/http/OnboardResponseWrapper.java | 23 + .../dto/registration/BiometricsDto.java | 3 + .../clientmanager/entity/UserBiometric.java | 6 +- .../repository/UserBiometricRepository.java | 75 + .../service/TemplateService.java | 1 - .../service/UserOnboardService.java | 311 ++- .../spi/RegistrationService.java | 4 + .../clientmanager/spi/SyncRestService.java | 4 +- .../clientmanager/util/SyncRestUtil.java | 15 + .../cbeffutil/jaxbclasses/BDBInfo.java | 4 +- .../cbeffutil/jaxbclasses/Biometric.java | 145 ++ .../cbeffutil/jaxbclasses/CbeffConstant.java | 25 + .../cbeffutil/jaxbclasses/QualityType.java | 3 + .../target/classes/DesiredCapabilities.json | 17 + .../target/classes/config.properties | 5 + assets/svg/success_message_icon.svg | 23 + lib/provider/global_provider.dart | 9 +- lib/ui/login_page.dart | 78 + lib/ui/onboard/home_page.dart | 14 +- lib/ui/onboard/onboarding_page.dart | 15 +- .../onboard/portrait/operational_tasks.dart | 9 +- lib/ui/onboard/portrait/task_card.dart | 4 +- ...tor_biometric_capture_scan_block_view.dart | 2071 +++++++++++++++++ .../operator_biometrics_capture_view.dart | 415 ++++ ...onboarding_biometrics_capture_control.dart | 115 + .../process_ui/widgets/language_selector.dart | 2 + .../biometric_capture_control_portrait.dart | 2 - ...biometric_capture_scan_block_portrait.dart | 265 ++- pigeon/biometrics.dart | 6 + 42 files changed, 4198 insertions(+), 437 deletions(-) create mode 100644 android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dao/UserBiometricDao.java create mode 100644 android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/http/OnboardError.java create mode 100644 android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/http/OnboardResponseWrapper.java create mode 100644 android/clientmanager/src/main/java/io/mosip/registration/clientmanager/repository/UserBiometricRepository.java create mode 100644 android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/Biometric.java create mode 100644 android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/CbeffConstant.java create mode 100644 androidReg-clientTest/target/classes/DesiredCapabilities.json create mode 100644 androidReg-clientTest/target/classes/config.properties create mode 100644 assets/svg/success_message_icon.svg create mode 100644 lib/ui/onboard/widgets/operator_biometric_capture_scan_block_view.dart create mode 100644 lib/ui/onboard/widgets/operator_biometrics_capture_view.dart create mode 100644 lib/ui/onboard/widgets/operator_onboarding_biometrics_capture_control.dart diff --git a/.gitignore b/.gitignore index 9c002f7b3..150940b6a 100644 --- a/.gitignore +++ b/.gitignore @@ -50,7 +50,7 @@ migrate_working_dir/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. -#.vscode/ +.vscode/ # Flutter/Dart/Pub related **/doc/api/ diff --git a/android/app/build.gradle b/android/app/build.gradle index 421dc1f3e..4c075afc1 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -57,7 +57,7 @@ android { shrinkResources false signingConfig signingConfigs.debug ndk { - abiFilters 'arm64-v8a', 'armeabi-v7a' // architectures: 'armeabi-v7a', 'arm64-v8a', 'armeabi', 'x86', 'x86_64' + abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86' , 'x86_64', 'armeabi'// architectures: 'armeabi-v7a', 'arm64-v8a', 'armeabi', 'x86', 'x86_64' } } } diff --git a/android/app/src/main/java/io/mosip/registration_client/HostApiModule.java b/android/app/src/main/java/io/mosip/registration_client/HostApiModule.java index 758cc8d8d..2b4514da6 100644 --- a/android/app/src/main/java/io/mosip/registration_client/HostApiModule.java +++ b/android/app/src/main/java/io/mosip/registration_client/HostApiModule.java @@ -28,6 +28,7 @@ import io.mosip.registration.clientmanager.service.Biometrics095Service; import io.mosip.registration.clientmanager.service.LoginService; import io.mosip.registration.clientmanager.service.TemplateService; +import io.mosip.registration.clientmanager.service.UserOnboardService; import io.mosip.registration.clientmanager.spi.AuditManagerService; import io.mosip.registration.clientmanager.spi.MasterDataService; import io.mosip.registration.clientmanager.spi.PacketService; @@ -136,8 +137,8 @@ ProcessSpecDetailsApi getProcessSpecDetailsApi(IdentitySchemaRepository identity @Provides @Singleton - BiometricsDetailsApi getBiometricsDetailsApi(AuditManagerService auditManagerService, ObjectMapper objectMapper, Biometrics095Service biometrics095Service, RegistrationService registrationService, GlobalParamRepository globalParamRepository) { - return new BiometricsDetailsApi(auditManagerService, objectMapper, biometrics095Service, registrationService, globalParamRepository); + BiometricsDetailsApi getBiometricsDetailsApi(AuditManagerService auditManagerService, ObjectMapper objectMapper, Biometrics095Service biometrics095Service, RegistrationService registrationService, GlobalParamRepository globalParamRepository, UserOnboardService userOnboardService) { + return new BiometricsDetailsApi(auditManagerService, objectMapper,biometrics095Service,registrationService,globalParamRepository,userOnboardService); } diff --git a/android/app/src/main/java/io/mosip/registration_client/api_services/BiometricsDetailsApi.java b/android/app/src/main/java/io/mosip/registration_client/api_services/BiometricsDetailsApi.java index 99a1396ae..4fce47c8e 100644 --- a/android/app/src/main/java/io/mosip/registration_client/api_services/BiometricsDetailsApi.java +++ b/android/app/src/main/java/io/mosip/registration_client/api_services/BiometricsDetailsApi.java @@ -29,8 +29,11 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -54,6 +57,7 @@ import io.mosip.registration.clientmanager.repository.GlobalParamRepository; import io.mosip.registration.clientmanager.service.Biometrics095Service; import io.mosip.registration.clientmanager.service.RegistrationServiceImpl; +import io.mosip.registration.clientmanager.service.UserOnboardService; import io.mosip.registration.clientmanager.spi.AuditManagerService; import io.mosip.registration.clientmanager.spi.RegistrationService; import io.mosip.registration.clientmanager.util.UserInterfaceHelperService; @@ -70,8 +74,10 @@ public class BiometricsDetailsApi implements BiometricsPigeon.BiometricsApi { private final Biometrics095Service biometricsService; private final RegistrationService registrationService; private final GlobalParamRepository globalParamRepository; + private final UserOnboardService userOnboardService; + private Modality currentModality; - private static final String TAG="BiometricsDetailApi"; + private static final String TAG = "BiometricsDetailApi"; private String callbackId; private String fieldId; private String purpose; @@ -81,366 +87,587 @@ public class BiometricsDetailsApi implements BiometricsPigeon.BiometricsApi { private int qualityThreshold; List biometricsDtoList; - private List listBitmaps1=new ArrayList<>(); + private List listBitmaps1 = new ArrayList<>(); private byte[] byteArrayTester; - private List listByteArrayTester1=new ArrayList<>(); + private List listByteArrayTester1 = new ArrayList<>(); BiometricsPigeon.Result result1; + public List OPERATOR_EXCEPTIONS=new ArrayList<>(); + @Inject - public BiometricsDetailsApi(AuditManagerService auditManagerService, ObjectMapper objectMapper, Biometrics095Service biometrics095Service, RegistrationService registrationService,GlobalParamRepository globalParamRepository) { + public BiometricsDetailsApi(AuditManagerService auditManagerService, ObjectMapper objectMapper, + Biometrics095Service biometrics095Service, RegistrationService registrationService, + GlobalParamRepository globalParamRepository, UserOnboardService userOnboardService) { this.auditManagerService = auditManagerService; this.objectMapper = objectMapper; - this.biometricsService=biometrics095Service; - this.registrationService=registrationService; - this.globalParamRepository=globalParamRepository; + this.biometricsService = biometrics095Service; + this.registrationService = registrationService; + this.globalParamRepository = globalParamRepository; + this.userOnboardService = userOnboardService; } - public void setCallbackActivity(MainActivity mainActivity){ - this.activity=mainActivity; + public void setCallbackActivity(MainActivity mainActivity) { + this.activity = mainActivity; } - @Override - public void invokeDiscoverSbi(@NonNull String fieldId, @NonNull String modality, @NonNull BiometricsPigeon.Result result) { + public void invokeDiscoverSbi(@NonNull String fieldId, @NonNull String modality, + @NonNull BiometricsPigeon.Result result) { auditManagerService.audit(AuditEvent.BIOMETRIC_CAPTURE, Components.REGISTRATION); currentModality = getModality(modality); - this.fieldId=fieldId; + this.fieldId = fieldId; discoverSBI(); - result1=result; + result1 = result; } @Override - public void getBestBiometrics(@NonNull String fieldId, @NonNull String modality, @NonNull BiometricsPigeon.Result> result) { - try{ - RegistrationDto registrationDto=registrationService.getRegistrationDto(); - ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); - String json; - List jsonList=new ArrayList<>(); - biometricsDtoList=registrationDto.getBestBiometrics(fieldId,getModality(modality)); - for(int i=0;i> result) { + + if (fieldId.equals("operatorBiometrics")) { + try { + biometricsDtoList=new ArrayList<>(); + ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); + String json; + List jsonList = new ArrayList<>(); + + for (BiometricsDto dto : userOnboardService.getOperatorBiometrics()) { + if (modality.equals("Face") && dto.getBioSubType()==null) { + biometricsDtoList.add(dto); + } + if(matchOperatorModality(dto.getBioSubType(),modality)){ + biometricsDtoList.add(dto); + } + } + + + for (int i = 0; i < biometricsDtoList.size(); i++) { + json = ow.writeValueAsString(biometricsDtoList.get(i)); + jsonList.add(json); + } + + + result.success(jsonList); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + } else { + try { + RegistrationDto registrationDto = registrationService.getRegistrationDto(); + ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); + String json; + List jsonList = new ArrayList<>(); + biometricsDtoList = registrationDto.getBestBiometrics(fieldId, getModality(modality)); + for (int i = 0; i < biometricsDtoList.size(); i++) { + json = ow.writeValueAsString(biometricsDtoList.get(i)); + jsonList.add(json); + } + result.success(jsonList); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } - result.success(jsonList); - }catch (Exception e){ - Log.e(TAG,e.getMessage()); } } @Override - public void getBiometrics(@NonNull String fieldId, @NonNull String modality, @NonNull Long attempt, @NonNull BiometricsPigeon.Result> result) { - try{ - RegistrationDto registrationDto=registrationService.getRegistrationDto(); + public void getBiometrics(@NonNull String fieldId, @NonNull String modality, @NonNull Long attempt, + @NonNull BiometricsPigeon.Result> result) { + try { + RegistrationDto registrationDto = registrationService.getRegistrationDto(); ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); String json; - List jsonList=new ArrayList<>(); - biometricsDtoList=registrationDto.getBiometrics(fieldId,getModality(modality),attempt.intValue()-1); - for(int i=0;i jsonList = new ArrayList<>(); + biometricsDtoList = registrationDto.getBiometrics(fieldId, getModality(modality), attempt.intValue() - 1); + for (int i = 0; i < biometricsDtoList.size(); i++) { + json = ow.writeValueAsString(biometricsDtoList.get(i)); jsonList.add(json); } result.success(jsonList); - }catch(Exception e){ - Log.e(TAG,e.getMessage()); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } } @Override - public void extractImageValues(@NonNull String fieldId, @NonNull String modality, @NonNull BiometricsPigeon.Result> result) { - List listBitmaps=new ArrayList<>(); - List listByteArrayTester=new ArrayList<>(); - try{ - RegistrationDto registrationDto=registrationService.getRegistrationDto(); - ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); - String json; - List jsonList=new ArrayList<>(); + public void extractImageValues(@NonNull String fieldId, @NonNull String modality, + @NonNull BiometricsPigeon.Result> result) { + List listBitmaps = new ArrayList<>(); + List listByteArrayTester = new ArrayList<>(); + if (fieldId.equals("operatorBiometrics")) { + try { - switch (getModality(modality)) { - case FACE: - case EXCEPTION_PHOTO: - { - try{ - Bitmap var5; - ByteArrayInputStream bais = new ByteArrayInputStream(CryptoUtil.base64decoder.decode(registrationDto.getBestBiometrics(fieldId,getModality(modality)).get(0).getBioValue())); - DataInputStream inputStream = new DataInputStream(bais); - FaceBDIR faceBDIR = new FaceBDIR(inputStream); - byte[] bytes = faceBDIR.getRepresentation().getRepresentationData().getImageData().getImage(); - var5 = (new JP2Decoder(bytes)).decode(); - listBitmaps.add(var5); - }catch(Exception e){ - Log.e(TAG,e.getMessage()); - } - } - break; - case FINGERPRINT_SLAB_LEFT: - case FINGERPRINT_SLAB_THUMBS: - case FINGERPRINT_SLAB_RIGHT: - { - try{ - Bitmap var5; - for (int i = 0; i < registrationDto.getBestBiometrics(fieldId,getModality(modality)).size(); i++) { - ByteArrayInputStream bais = new ByteArrayInputStream(CryptoUtil.base64decoder.decode(registrationDto.getBestBiometrics(fieldId,getModality(modality)).get(i).getBioValue())); + + ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); + String json; + List jsonList = new ArrayList<>(); + List biometricsDtoListtemp = new ArrayList<>(); + + switch (getModality(modality)) { + case FACE: + case EXCEPTION_PHOTO: { + try { + BiometricsDto biometricsDtotemp = new BiometricsDto(); + + for (BiometricsDto dto : userOnboardService.getOperatorBiometrics()) { + + if (modality.equals("Face") && dto.getBioSubType()==null) { + biometricsDtotemp = dto; + break; + } + } + Bitmap var5; + ByteArrayInputStream bais = new ByteArrayInputStream( + CryptoUtil.base64decoder.decode(biometricsDtotemp.getBioValue())); DataInputStream inputStream = new DataInputStream(bais); - FingerBDIR fingerBDIR = new FingerBDIR(inputStream); - byte[] bytes = fingerBDIR.getRepresentation().getRepresentationBody().getImageData().getImage(); + FaceBDIR faceBDIR = new FaceBDIR(inputStream); + byte[] bytes = faceBDIR.getRepresentation().getRepresentationData().getImageData() + .getImage(); var5 = (new JP2Decoder(bytes)).decode(); listBitmaps.add(var5); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } - }catch (Exception e){ - Log.e(TAG,e.getMessage()); } + break; + case FINGERPRINT_SLAB_LEFT: + case FINGERPRINT_SLAB_THUMBS: + case FINGERPRINT_SLAB_RIGHT: { + try { + + for (BiometricsDto dto : userOnboardService.getOperatorBiometrics()) { + + if (matchOperatorModality(dto.getBioSubType(),modality)) { + biometricsDtoListtemp.add(dto); + } + } + Bitmap var5; + for (int i = 0; i < biometricsDtoListtemp.size(); i++) { + ByteArrayInputStream bais = new ByteArrayInputStream( + CryptoUtil.base64decoder.decode(biometricsDtoListtemp.get(i).getBioValue())); + DataInputStream inputStream = new DataInputStream(bais); + FingerBDIR fingerBDIR = new FingerBDIR(inputStream); + byte[] bytes = fingerBDIR.getRepresentation().getRepresentationBody().getImageData() + .getImage(); + var5 = (new JP2Decoder(bytes)).decode(); + listBitmaps.add(var5); + } + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + } + break; + case IRIS_DOUBLE: { + try { + + + for (BiometricsDto dto : userOnboardService.getOperatorBiometrics()) { + if (matchOperatorModality(dto.getBioSubType(),modality)) { + biometricsDtoListtemp.add(dto); + + } + } + + Bitmap var5; + for (int i = 0; i < biometricsDtoListtemp.size(); i++) { + ByteArrayInputStream bais = new ByteArrayInputStream( + CryptoUtil.base64decoder.decode(biometricsDtoListtemp.get(0).getBioValue())); + DataInputStream inputStream = new DataInputStream(bais); + IrisBDIR irisBDIR = new IrisBDIR(inputStream); + byte[] bytes = irisBDIR.getRepresentation().getRepresentationData().getImageData() + .getImage(); + var5 = (new JP2Decoder(bytes)).decode(); + listBitmaps.add(var5); + } + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + } + break; } - break; - case IRIS_DOUBLE: - { - try{ - Bitmap var5; - for (int i = 0; i < registrationDto.getBestBiometrics(fieldId,getModality(modality)).size(); i++){ - ByteArrayInputStream bais = new ByteArrayInputStream(CryptoUtil.base64decoder.decode(registrationDto.getBestBiometrics(fieldId,getModality(modality)).get(0).getBioValue())); + + for (int i = 0; i < listBitmaps.size(); i++) { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + listBitmaps.get(i).compress(Bitmap.CompressFormat.PNG, 100, stream); + byteArrayTester = stream.toByteArray(); + listByteArrayTester.add(byteArrayTester); + } + + listByteArrayTester1 = listByteArrayTester; + result.success(listByteArrayTester1); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + } else { + try { + RegistrationDto registrationDto = registrationService.getRegistrationDto(); + ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); + String json; + List jsonList = new ArrayList<>(); + + switch (getModality(modality)) { + case FACE: + case EXCEPTION_PHOTO: { + try { + Bitmap var5; + ByteArrayInputStream bais = new ByteArrayInputStream( + CryptoUtil.base64decoder.decode(registrationDto + .getBestBiometrics(fieldId, getModality(modality)).get(0).getBioValue())); DataInputStream inputStream = new DataInputStream(bais); - IrisBDIR irisBDIR = new IrisBDIR(inputStream); - byte[] bytes = irisBDIR.getRepresentation().getRepresentationData().getImageData().getImage(); + FaceBDIR faceBDIR = new FaceBDIR(inputStream); + byte[] bytes = faceBDIR.getRepresentation().getRepresentationData().getImageData() + .getImage(); var5 = (new JP2Decoder(bytes)).decode(); listBitmaps.add(var5); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + } + break; + case FINGERPRINT_SLAB_LEFT: + case FINGERPRINT_SLAB_THUMBS: + case FINGERPRINT_SLAB_RIGHT: { + try { + Bitmap var5; + for (int i = 0; i < registrationDto.getBestBiometrics(fieldId, getModality(modality)) + .size(); i++) { + ByteArrayInputStream bais = new ByteArrayInputStream(CryptoUtil.base64decoder + .decode(registrationDto.getBestBiometrics(fieldId, getModality(modality)).get(i) + .getBioValue())); + DataInputStream inputStream = new DataInputStream(bais); + FingerBDIR fingerBDIR = new FingerBDIR(inputStream); + byte[] bytes = fingerBDIR.getRepresentation().getRepresentationBody().getImageData() + .getImage(); + var5 = (new JP2Decoder(bytes)).decode(); + listBitmaps.add(var5); + } + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + } + break; + case IRIS_DOUBLE: { + try { + Bitmap var5; + + for (int i = 0; i < registrationDto.getBestBiometrics(fieldId, getModality(modality)) + .size(); i++) { + ByteArrayInputStream bais = new ByteArrayInputStream(CryptoUtil.base64decoder + .decode(registrationDto.getBestBiometrics(fieldId, getModality(modality)).get(0) + .getBioValue())); + DataInputStream inputStream = new DataInputStream(bais); + IrisBDIR irisBDIR = new IrisBDIR(inputStream); + byte[] bytes = irisBDIR.getRepresentation().getRepresentationData().getImageData() + .getImage(); + var5 = (new JP2Decoder(bytes)).decode(); + listBitmaps.add(var5); + } + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } - }catch (Exception e){ - Log.e(TAG,e.getMessage()); } + break; } - break; - } - for (int i = 0; i < listBitmaps.size(); i++) { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - listBitmaps.get(i).compress(Bitmap.CompressFormat.PNG, 100, stream); - byteArrayTester= stream.toByteArray(); - listByteArrayTester.add(byteArrayTester); - } + for (int i = 0; i < listBitmaps.size(); i++) { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + listBitmaps.get(i).compress(Bitmap.CompressFormat.PNG, 100, stream); + byteArrayTester = stream.toByteArray(); + listByteArrayTester.add(byteArrayTester); + } - listByteArrayTester1=listByteArrayTester; - result.success(listByteArrayTester1); - }catch (Exception e){ - Log.e(TAG,e.getMessage()); + listByteArrayTester1 = listByteArrayTester; + result.success(listByteArrayTester1); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } } } @Override - public void extractImageValuesByAttempt(@NonNull String fieldId, @NonNull String modality, @NonNull Long attempt, @NonNull BiometricsPigeon.Result> result) { - List listBitmaps=new ArrayList<>(); - List listByteArrayTester=new ArrayList<>(); - try{ - RegistrationDto registrationDto=registrationService.getRegistrationDto(); + public void extractImageValuesByAttempt(@NonNull String fieldId, @NonNull String modality, @NonNull Long attempt, + @NonNull BiometricsPigeon.Result> result) { + List listBitmaps = new ArrayList<>(); + List listByteArrayTester = new ArrayList<>(); + try { + RegistrationDto registrationDto = registrationService.getRegistrationDto(); ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); String json; - List jsonList=new ArrayList<>(); + List jsonList = new ArrayList<>(); switch (getModality(modality)) { case FACE: - case EXCEPTION_PHOTO: - { - try{ + case EXCEPTION_PHOTO: { + try { Bitmap var5; - ByteArrayInputStream bais = new ByteArrayInputStream(CryptoUtil.base64decoder.decode(registrationDto.getBiometrics(fieldId,getModality(modality),attempt.intValue()-1).get(0).getBioValue())); + ByteArrayInputStream bais = new ByteArrayInputStream(CryptoUtil.base64decoder.decode( + registrationDto.getBiometrics(fieldId, getModality(modality), attempt.intValue() - 1) + .get(0).getBioValue())); DataInputStream inputStream = new DataInputStream(bais); FaceBDIR faceBDIR = new FaceBDIR(inputStream); byte[] bytes = faceBDIR.getRepresentation().getRepresentationData().getImageData().getImage(); var5 = (new JP2Decoder(bytes)).decode(); listBitmaps.add(var5); - }catch(Exception e){ - Log.e(TAG,e.getMessage()); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } } - break; + break; case FINGERPRINT_SLAB_LEFT: case FINGERPRINT_SLAB_THUMBS: - case FINGERPRINT_SLAB_RIGHT: - { - try{ + case FINGERPRINT_SLAB_RIGHT: { + try { Bitmap var5; - for (int i = 0; i < registrationDto.getBiometrics(fieldId,getModality(modality),attempt.intValue()-1).size(); i++) { - ByteArrayInputStream bais = new ByteArrayInputStream(CryptoUtil.base64decoder.decode(registrationDto.getBiometrics(fieldId,getModality(modality),attempt.intValue()-1).get(i).getBioValue())); + for (int i = 0; i < registrationDto + .getBiometrics(fieldId, getModality(modality), attempt.intValue() - 1).size(); i++) { + ByteArrayInputStream bais = new ByteArrayInputStream( + CryptoUtil.base64decoder.decode(registrationDto + .getBiometrics(fieldId, getModality(modality), attempt.intValue() - 1) + .get(i).getBioValue())); DataInputStream inputStream = new DataInputStream(bais); FingerBDIR fingerBDIR = new FingerBDIR(inputStream); - byte[] bytes = fingerBDIR.getRepresentation().getRepresentationBody().getImageData().getImage(); + byte[] bytes = fingerBDIR.getRepresentation().getRepresentationBody().getImageData() + .getImage(); var5 = (new JP2Decoder(bytes)).decode(); listBitmaps.add(var5); } - }catch (Exception e){ - Log.e(TAG,e.getMessage()); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } } - break; - case IRIS_DOUBLE: - { - try{ + break; + case IRIS_DOUBLE: { + try { Bitmap var5; - for (int i = 0; i < registrationDto.getBiometrics(fieldId,getModality(modality),attempt.intValue()-1).size(); i++){ - ByteArrayInputStream bais = new ByteArrayInputStream(CryptoUtil.base64decoder.decode(registrationDto.getBiometrics(fieldId,getModality(modality),attempt.intValue()-1).get(0).getBioValue())); + for (int i = 0; i < registrationDto + .getBiometrics(fieldId, getModality(modality), attempt.intValue() - 1).size(); i++) { + ByteArrayInputStream bais = new ByteArrayInputStream( + CryptoUtil.base64decoder.decode(registrationDto + .getBiometrics(fieldId, getModality(modality), attempt.intValue() - 1) + .get(0).getBioValue())); DataInputStream inputStream = new DataInputStream(bais); IrisBDIR irisBDIR = new IrisBDIR(inputStream); - byte[] bytes = irisBDIR.getRepresentation().getRepresentationData().getImageData().getImage(); + byte[] bytes = irisBDIR.getRepresentation().getRepresentationData().getImageData() + .getImage(); var5 = (new JP2Decoder(bytes)).decode(); listBitmaps.add(var5); } - }catch (Exception e){ - Log.e(TAG,e.getMessage()); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } } - break; + break; } for (int i = 0; i < listBitmaps.size(); i++) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); listBitmaps.get(i).compress(Bitmap.CompressFormat.PNG, 100, stream); - byteArrayTester= stream.toByteArray(); + byteArrayTester = stream.toByteArray(); listByteArrayTester.add(byteArrayTester); } - - listByteArrayTester1=listByteArrayTester; + listByteArrayTester1 = listByteArrayTester; result.success(listByteArrayTester1); - }catch (Exception e){ - Log.e(TAG,e.getMessage()); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } } - @Override - public void incrementBioAttempt(@NonNull String fieldId, @NonNull String modality, @NonNull BiometricsPigeon.Result result) { - try{ - RegistrationDto registrationDto=registrationService.getRegistrationDto(); - int i=registrationDto.incrementBioAttempt(fieldId,getModality(modality)); + public void incrementBioAttempt(@NonNull String fieldId, @NonNull String modality, + @NonNull BiometricsPigeon.Result result) { + try { + RegistrationDto registrationDto = registrationService.getRegistrationDto(); + int i = registrationDto.incrementBioAttempt(fieldId, getModality(modality)); result.success(Long.valueOf(i)); - }catch(Exception e){ - Log.e(TAG,e.getMessage()); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } } @Override - public void getBioAttempt(@NonNull String fieldId, @NonNull String modality, @NonNull BiometricsPigeon.Result result) { - try{ - RegistrationDto registrationDto=registrationService.getRegistrationDto(); - int i=registrationDto.getBioAttempt(fieldId,getModality(modality)); + public void getBioAttempt(@NonNull String fieldId, @NonNull String modality, + @NonNull BiometricsPigeon.Result result) { + try { + RegistrationDto registrationDto = registrationService.getRegistrationDto(); + int i = registrationDto.getBioAttempt(fieldId, getModality(modality)); result.success(Long.valueOf(i)); - }catch(Exception e){ - Log.e(TAG,e.getMessage()); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } } @Override - public void addBioException(@NonNull String fieldId, @NonNull String modality, @NonNull String attribute, @NonNull BiometricsPigeon.Result result) { - try{ - RegistrationDto registrationDto=registrationService.getRegistrationDto(); - registrationDto.addBioException(fieldId,getModality(modality),attribute); - result.success("ok"); - }catch(Exception e){ - Log.e(TAG,e.getMessage()); + public void startOperatorOnboarding(@NonNull BiometricsPigeon.Result result) { + try { + userOnboardService.getOperatorBiometrics().clear(); + result.success("Ok"); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } } @Override - public void removeBioException(@NonNull String fieldId, @NonNull String modality, @NonNull String attribute, @NonNull BiometricsPigeon.Result result) { + public void saveOperatorBiometrics(@NonNull BiometricsPigeon.Result result) { try{ - RegistrationDto registrationDto=registrationService.getRegistrationDto(); - registrationDto.removeBioException(fieldId,getModality(modality),attribute); - result.success("ok"); - }catch(Exception e){ - Log.e(TAG,e.getMessage()); + userOnboardService.onboardOperator(userOnboardService.getOperatorBiometrics(), () -> { + if(userOnboardService.getIsOnboardSuccess()) { + result.success("OK"); + } + }); + }catch (Exception e){ + Log.e(TAG, e.getMessage()); + } + } + + @Override + public void addBioException(@NonNull String fieldId, @NonNull String modality, @NonNull String attribute, + @NonNull BiometricsPigeon.Result result) { + try { + if(fieldId.equals("operatorBiometrics")){ + + + OPERATOR_EXCEPTIONS.add(attribute); + + +// String key = String.format(BIO_KEY, fieldId, modality.name()); +// ATTEMPTS.put(key, new AtomicInteger(0)); +// for(String attribute : modality.getAttributes()) { +// this.biometrics.keySet() +// .removeIf(k -> k.startsWith(String.format(BIO_KEY_PATTERN, fieldId, attribute))); +// } + result.success("ok"); + }else{ + RegistrationDto registrationDto = registrationService.getRegistrationDto(); + registrationDto.addBioException(fieldId, getModality(modality), attribute); + result.success("ok"); + } + + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + } + + @Override + public void removeBioException(@NonNull String fieldId, @NonNull String modality, @NonNull String attribute, + @NonNull BiometricsPigeon.Result result) { + try { + if(fieldId.equals("operatorBiometrics")){ + OPERATOR_EXCEPTIONS.remove(attribute); + + + result.success("ok"); + }else{ + RegistrationDto registrationDto = registrationService.getRegistrationDto(); + registrationDto.removeBioException(fieldId, getModality(modality), attribute); + result.success("ok"); + } + + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } } @Override public void getMapValue(@NonNull String key, @NonNull BiometricsPigeon.Result result) { - String response=globalParamRepository.getCachedStringGlobalParam(key); - result.success(response); + String response = globalParamRepository.getCachedStringGlobalParam(key); + result.success(response); } @Override public void getAgeGroup(@NonNull BiometricsPigeon.Result result) { - try{ - RegistrationDto registrationDto=registrationService.getRegistrationDto(); - Map age_group=registrationDto.getAgeGroup(); + try { + RegistrationDto registrationDto = registrationService.getRegistrationDto(); + Map age_group = registrationDto.getAgeGroup(); result.success((String) age_group.get("ageGroup")); - }catch(Exception e){ - Log.e(TAG,e.getMessage()); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } } @Override - public void conditionalBioAttributeValidation(@NonNull String fieldId, @NonNull String expression, @NonNull BiometricsPigeon.Result result) { - try{ - RegistrationDto registrationDto=registrationService.getRegistrationDto(); - List biometricsDtoList=new ArrayList<>(); + public void conditionalBioAttributeValidation(@NonNull String fieldId, @NonNull String expression, + @NonNull BiometricsPigeon.Result result) { + try { + RegistrationDto registrationDto = registrationService.getRegistrationDto(); + List biometricsDtoList = new ArrayList<>(); for (Modality modality : Modality.values()) { - List temp= registrationDto.getBestBiometrics(fieldId,modality); - biometricsDtoList.addAll(temp); + List temp = registrationDto.getBestBiometrics(fieldId, modality); + biometricsDtoList.addAll(temp); } - Map dataContext=new HashMap(); - Pattern REGEX_PATTERN = - Pattern.compile("[a-zA-Z]+"); + Map dataContext = new HashMap(); + Pattern REGEX_PATTERN = Pattern.compile("[a-zA-Z]+"); - Matcher matcher=REGEX_PATTERN.matcher(expression); + Matcher matcher = REGEX_PATTERN.matcher(expression); while (matcher.find()) { - dataContext.put(matcher.group(),false); - for (BiometricsDto dto:biometricsDtoList) { - if(dto.getBioSubType()!=null){ - if(customMatcher(dto.getBioSubType(),matcher.group())){ - dataContext.put(matcher.group(),true); + dataContext.put(matcher.group(), false); + for (BiometricsDto dto : biometricsDtoList) { + if (dto.getBioSubType() != null) { + if (customMatcher(dto.getBioSubType(), matcher.group())) { + dataContext.put(matcher.group(), true); break; } - } - else{ - if(dto.getModality().toUpperCase().matches(matcher.group().toUpperCase())){ - dataContext.put(matcher.group(),true); + } else { + if (dto.getModality().toUpperCase().matches(matcher.group().toUpperCase())) { + dataContext.put(matcher.group(), true); break; } } } } Log.i(TAG, "Printing Map: " + dataContext); - Boolean response=UserInterfaceHelperService.evaluateValidationExpression(expression,dataContext); + Boolean response = UserInterfaceHelperService.evaluateValidationExpression(expression, dataContext); result.success(response); - }catch(Exception e){ - Log.e(TAG,e.getMessage()); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); } } - public static Boolean customMatcher(String str1,String str2){ - Boolean result=false; - if(str1.matches("Left IndexFinger") && str2.matches("leftIndex")){ - result=true; - } - if(str1.matches("Left MiddleFinger") && str2.matches("leftMiddle")){ - result=true; - }if(str1.matches("Left RingFinger") && str2.matches("leftRing")){ - result=true; - }if(str1.matches("Left LittleFinger") && str2.matches("leftLittle")){ - result=true; - }if(str1.matches("Right IndexFinger") && str2.matches("rightIndex")){ - result=true; - }if(str1.matches("Right MiddleFinger") && str2.matches("rightMiddle")){ - result=true; - }if(str1.matches("Right RingFinger") && str2.matches("rightRing")){ - result=true; - }if(str1.matches("Right LittleFinger") && str2.matches("rightLittle")){ - result=true; - }if(str1.matches("Left Thumb") && str2.matches("leftThumb")){ - result=true; - }if(str1.matches("Right Thumb") && str2.matches("rightThumb")){ - result=true; - }if(str1.matches("Left") && str2.matches("leftEye")){ - result=true; - }if(str1.matches("Right") && str2.matches("rightEye")){ - result=true; - }if(str1==null && str2.matches("face")){ - result=true; + public static Boolean customMatcher(String str1, String str2) { + Boolean result = false; + if (str1.matches("Left IndexFinger") && str2.matches("leftIndex")) { + result = true; + } + if (str1.matches("Left MiddleFinger") && str2.matches("leftMiddle")) { + result = true; + } + if (str1.matches("Left RingFinger") && str2.matches("leftRing")) { + result = true; + } + if (str1.matches("Left LittleFinger") && str2.matches("leftLittle")) { + result = true; + } + if (str1.matches("Right IndexFinger") && str2.matches("rightIndex")) { + result = true; + } + if (str1.matches("Right MiddleFinger") && str2.matches("rightMiddle")) { + result = true; + } + if (str1.matches("Right RingFinger") && str2.matches("rightRing")) { + result = true; + } + if (str1.matches("Right LittleFinger") && str2.matches("rightLittle")) { + result = true; + } + if (str1.matches("Left Thumb") && str2.matches("leftThumb")) { + result = true; + } + if (str1.matches("Right Thumb") && str2.matches("rightThumb")) { + result = true; + } + if (str1.matches("Left") && str2.matches("leftEye")) { + result = true; + } + if (str1.matches("Right") && str2.matches("rightEye")) { + result = true; + } + if (str1 == null && str2.matches("face")) { + result = true; } return result; } - public static Map objectToMap(Object object) { Map map = new HashMap<>(); @@ -464,11 +691,10 @@ public static Map objectToMap(Object object) { return map; } - private void queryPackage(Intent intent) throws ClientCheckedException { List activities = activity.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_ALL); - //if(activities.size() == 0) - // throw new ClientCheckedException("Supported apps not found!"); + // if(activities.size() == 0) + // throw new ClientCheckedException("Supported apps not found!"); } private Modality getModality(String modality) { @@ -490,16 +716,75 @@ private Modality getModality(String modality) { return currentModality; } + + private String attributeToBioSubType(String attribute){ +// rightThumb, leftThumb,leftIndex, leftLittle, leftRing, leftMiddle,rightEye, leftEye,rightRing, rightIndex, rightMiddle, rightLittle + if(attribute.equals("rightThumb")){ + return "Right Thumb"; + }else if(attribute.equals("leftThumb")){ + return "Left Thumb"; + }else if(attribute.equals("leftIndex")){ + return "Left IndexFinger"; + }else if(attribute.equals("leftLittle")){ + return "Left LittleFinger"; + }else if(attribute.equals("leftRing")){ + return "Left RingFinger"; + }else if(attribute.equals("leftMiddle")){ + return "Left MiddleFinger"; + }else if(attribute.equals("rightEye")){ + return "Right"; + }else if(attribute.equals("leftEye")){ + return "Left"; + }else if(attribute.equals("rightRing")){ + return "Right RingFinger"; + }else if(attribute.equals("rightIndex")){ + return "Right IndexFinger"; + }else if(attribute.equals("rightMiddle")){ + return "Right MiddleFinger"; + }else if(attribute.equals("rightLittle")){ + return "Right LittleFinger"; + } + return ""; + } + private boolean matchOperatorModality(String bioSubType,String modality) { + boolean result =false; + if (modality.equals("Iris")) { + if(bioSubType!=null && (bioSubType.equals("Left")||bioSubType.equals("Right"))){ + result=true; + + } + } else if (modality.equals("LeftHand")) { + if(bioSubType!=null && (bioSubType.equals("Left LittleFinger")||bioSubType.equals("Left MiddleFinger")||bioSubType.equals("Left IndexFinger")||bioSubType.equals("Left RingFinger"))){ + result=true; + + } + + } else if (modality.equals("RightHand")) { + if(bioSubType!=null && (bioSubType.equals("Right LittleFinger")||bioSubType.equals("Right MiddleFinger")||bioSubType.equals("Right IndexFinger")||bioSubType.equals("Right RingFinger"))){ + result=true; + + } + } else if (modality.equals("Thumbs")) { + if(bioSubType!=null && (bioSubType.equals("Left Thumb")||bioSubType.equals("Right Thumb"))){ + result=true; + + } + } + + return result; + } + private void discoverSBI() { try { - Log.i("SBI","Started to discover SBI"); + Log.i("SBI", "Started to discover SBI"); Intent intent = new Intent(); intent.setAction(RegistrationConstants.DISCOVERY_INTENT_ACTION); queryPackage(intent); DiscoverRequest discoverRequest = new DiscoverRequest(); - discoverRequest.setType(currentModality == Modality.EXCEPTION_PHOTO ? SingleType.FACE.value() : - currentModality.getSingleType().value()); - intent.putExtra(RegistrationConstants.SBI_INTENT_REQUEST_KEY, objectMapper.writeValueAsBytes(discoverRequest)); + discoverRequest.setType(currentModality == Modality.EXCEPTION_PHOTO ? SingleType.FACE.value() + : currentModality.getSingleType().value()); + intent.putExtra(RegistrationConstants.SBI_INTENT_REQUEST_KEY, + objectMapper.writeValueAsBytes(discoverRequest)); activity.startActivityForResult(intent, 1); } catch (Exception ex) { auditManagerService.audit(AuditEvent.DISCOVER_SBI_FAILED, Components.REGISTRATION, ex.getMessage()); @@ -509,7 +794,7 @@ private void discoverSBI() { private void info(String callbackId) { if (callbackId == null) { - Log.e(TAG,"No SBI found"); + Log.e(TAG, "No SBI found"); return; } @@ -526,16 +811,16 @@ private void info(String callbackId) { private void rcapture(String callbackId, String deviceId) { if (deviceId == null || callbackId == null) { - Log.e(TAG,"No SBI found!"); + Log.e(TAG, "No SBI found!"); return; } try { Intent intent = new Intent(); - //callbackId = callbackId.replace("\\.info",""); + // callbackId = callbackId.replace("\\.info",""); intent.setAction(callbackId + RegistrationConstants.R_CAPTURE_INTENT_ACTION); queryPackage(intent); - Log.e(TAG,"Initiating capture request : "); + Log.e(TAG, "Initiating capture request : "); CaptureRequest captureRequest = biometricsService.getRCaptureRequest(currentModality, deviceId, getExceptionAttributes()); intent.putExtra("input", objectMapper.writeValueAsBytes(captureRequest)); @@ -573,25 +858,115 @@ public void parseDeviceInfoResponse(Bundle bundle) { rcapture(callbackId, serialNo); } +// public void removeDuplicatesFromOperatorBiometricList(String bioSubType){ +// List biometricsDtoListCopy=new ArrayList<>(); +// biometricsDtoListCopy.addAll(userOnboardService.getOperatorBiometrics()); +// biometricsDtoListCopy.forEach(biometricsDto -> { +// if(biometricsDto.getBioSubType()==null && bioSubType==null){ +// userOnboardService.getOperatorBiometrics().remove(biometricsDto); +// return; +// } +// if(biometricsDto.getBioSubType().equals(bioSubType)){ +// userOnboardService.getOperatorBiometrics().remove(biometricsDto); +// } +// }); +// +// } + + + + public void removeDuplicatesFromOperatorBiometricList(Modality modality){ + List biometricsDtoListCopy=new ArrayList<>(); + + userOnboardService.getOperatorBiometrics().forEach(biometricsDto -> { + if (modality==Modality.IRIS_DOUBLE) { + if(biometricsDto.getBioSubType()!=null && (biometricsDto.getBioSubType().equals("Left")||biometricsDto.getBioSubType().equals("Right"))){ + + }else{ + biometricsDtoListCopy.add(biometricsDto); + } + } else if (modality==Modality.FINGERPRINT_SLAB_LEFT) { + if(biometricsDto.getBioSubType()!=null &&(biometricsDto.getBioSubType().equals("Left LittleFinger")||biometricsDto.getBioSubType().equals("Left MiddleFinger")||biometricsDto.getBioSubType().equals("Left IndexFinger")||biometricsDto.getBioSubType().equals("Left RingFinger"))){ + + + }else{ + biometricsDtoListCopy.add(biometricsDto); + } + } else if (modality==Modality.FINGERPRINT_SLAB_RIGHT) { + if(biometricsDto.getBioSubType()!=null &&(biometricsDto.getBioSubType().equals("Right LittleFinger")||biometricsDto.getBioSubType().equals("Right MiddleFinger")||biometricsDto.getBioSubType().equals("Right IndexFinger")||biometricsDto.getBioSubType().equals("Right RingFinger"))){ + + + }else{ + biometricsDtoListCopy.add(biometricsDto); + } + }else if (modality==Modality.FINGERPRINT_SLAB_THUMBS) { + if(biometricsDto.getBioSubType()!=null &&(biometricsDto.getBioSubType().equals("Left Thumb")||biometricsDto.getBioSubType().equals("Right Thumb"))){ + + + }else{ + biometricsDtoListCopy.add(biometricsDto); + } + }else if (modality==Modality.FACE) { + if(biometricsDto.getBioSubType()==null){ + + }else{ + biometricsDtoListCopy.add(biometricsDto); + } + } + }); + userOnboardService.getOperatorBiometrics().clear(); + userOnboardService.getOperatorBiometrics().addAll(biometricsDtoListCopy); + + + } + public void parseRCaptureResponse(Bundle bundle) { try { + Uri uri = bundle.getParcelable(RegistrationConstants.SBI_INTENT_RESPONSE_KEY); InputStream respData = activity.getContentResolver().openInputStream(uri); List biometricsDtoList = biometricsService.handleRCaptureResponse(currentModality, respData, getExceptionAttributes()); - //if attempts is zero, there is no need to maintain the counter - currentAttempt = this.registrationService.getRegistrationDto().getBioAttempt(fieldId,currentModality); + // if attempts is zero, there is no need to maintain the counter + if (fieldId.equals("operatorBiometrics")) { + removeDuplicatesFromOperatorBiometricList(currentModality); + biometricsDtoList.forEach(biometricsDto -> {userOnboardService.getOperatorBiometrics().add(biometricsDto);}); + List biometricsDtoListCopy=new ArrayList<>(); + biometricsDtoListCopy.addAll(biometricsDtoList); + if(biometricsDtoListCopy!=null && OPERATOR_EXCEPTIONS!=null && !(OPERATOR_EXCEPTIONS.isEmpty())){ + for (String exception : OPERATOR_EXCEPTIONS) { + for (BiometricsDto biometricsDto : biometricsDtoListCopy) { + if(biometricsDto.getBioSubType()==null){ + break; + } + + if (biometricsDto.getBioSubType().equals(attributeToBioSubType(exception))) { + userOnboardService.getOperatorBiometrics().remove(biometricsDto); + biometricsDtoList.remove(biometricsDto); + } + } + } + } - biometricsDtoList.forEach( dto -> { - try { - this.registrationService.getRegistrationDto().addBiometric(fieldId, - (currentModality == Modality.EXCEPTION_PHOTO) || (currentModality == Modality.FACE) ? currentModality.getAttributes().get(0) : - Modality.getBioAttribute(dto.getBioSubType()), currentAttempt, dto); - result1.success("Ok"); - } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); } - }); + result1.success("Ok"); + } else { + currentAttempt = this.registrationService.getRegistrationDto().getBioAttempt(fieldId, currentModality); + biometricsDtoList.forEach(dto -> { + try { + this.registrationService.getRegistrationDto().addBiometric(fieldId, + (currentModality == Modality.EXCEPTION_PHOTO) || (currentModality == Modality.FACE) + ? currentModality.getAttributes().get(0) + : Modality.getBioAttribute(dto.getBioSubType()), + currentAttempt, dto); + + result1.success("Ok"); + } catch (Exception ex) { + Log.e(TAG, ex.getMessage(), ex); + } + }); + } } catch (Exception e) { auditManagerService.audit(AuditEvent.R_CAPTURE_PARSE_FAILED, Components.REGISTRATION, e.getMessage()); @@ -599,13 +974,15 @@ public void parseRCaptureResponse(Bundle bundle) { } } + private List getExceptionAttributes() { return currentModality.getAttributes().stream() - .filter( it -> - { + .filter(it -> { try { - return this.registrationService.getRegistrationDto().isBioException(fieldId, currentModality, it); - } catch (Exception e) {} + return this.registrationService.getRegistrationDto().isBioException(fieldId, currentModality, + it); + } catch (Exception e) { + } return false; }) .collect(Collectors.toList()); diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/AppModule.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/AppModule.java index d903c270e..9dc9dc452 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/AppModule.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/AppModule.java @@ -230,9 +230,9 @@ Biometrics095Service provideBiometrics095Service(ObjectMapper objectMapper, Audi @Singleton UserOnboardService provideUserOnboardService(ObjectMapper objectMapper, AuditManagerService auditManagerService, CertificateManagerService certificateManagerService, - SyncRestService syncRestService, CryptoManagerService cryptoManagerService) { + SyncRestService syncRestService, CryptoManagerService cryptoManagerService, RegistrationService registrationService, UserBiometricRepository userBiometricRepository, ClientCryptoManagerService clientCryptoManagerService) { return new UserOnboardService(appContext, objectMapper, auditManagerService, certificateManagerService, syncRestService, - cryptoManagerService); + cryptoManagerService, registrationService, userBiometricRepository, clientCryptoManagerService); } @Provides diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/ClientDatabase.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/ClientDatabase.java index 44cbc22a8..c53969a5d 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/ClientDatabase.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/ClientDatabase.java @@ -23,6 +23,7 @@ import io.mosip.registration.clientmanager.dao.RegistrationDao; import io.mosip.registration.clientmanager.dao.SyncJobDefDao; import io.mosip.registration.clientmanager.dao.TemplateDao; +import io.mosip.registration.clientmanager.dao.UserBiometricDao; import io.mosip.registration.clientmanager.dao.UserDetailDao; import io.mosip.registration.clientmanager.dao.UserPasswordDao; import io.mosip.registration.clientmanager.dao.UserTokenDao; @@ -43,6 +44,7 @@ import io.mosip.registration.clientmanager.entity.RegistrationCenter; import io.mosip.registration.clientmanager.entity.SyncJobDef; import io.mosip.registration.clientmanager.entity.Template; +import io.mosip.registration.clientmanager.entity.UserBiometric; import io.mosip.registration.clientmanager.entity.UserDetail; import io.mosip.registration.clientmanager.entity.UserPassword; import io.mosip.registration.clientmanager.entity.UserToken; @@ -55,7 +57,7 @@ MachineMaster.class, DocumentType.class, DynamicField.class, ApplicantValidDocument.class, Template.class, KeyStore.class, Location.class, GlobalParam.class, IdentitySchema.class, LocationHierarchy.class, - BlocklistedWord.class, SyncJobDef.class, UserDetail.class, UserPassword.class, JobTransaction.class, + BlocklistedWord.class, SyncJobDef.class, UserDetail.class, UserBiometric.class, UserPassword.class, JobTransaction.class, CACertificateStore.class, Language.class, Audit.class, FileSignature.class}, version = 1, exportSchema = false) public abstract class ClientDatabase extends RoomDatabase { @@ -108,6 +110,8 @@ public static ClientDatabase buildDatabase(Context context) { public abstract UserDetailDao userDetailDao(); + public abstract UserBiometricDao userBiometricDao(); + public abstract UserPasswordDao userPasswordDao(); public abstract JobTransactionDao jobTransactionDao(); diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/RoomModule.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/RoomModule.java index 499852664..7ff16986d 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/RoomModule.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/RoomModule.java @@ -43,9 +43,11 @@ import io.mosip.registration.clientmanager.dao.RegistrationDao; import io.mosip.registration.clientmanager.dao.SyncJobDefDao; import io.mosip.registration.clientmanager.dao.TemplateDao; +import io.mosip.registration.clientmanager.dao.UserBiometricDao; import io.mosip.registration.clientmanager.dao.UserDetailDao; import io.mosip.registration.clientmanager.dao.UserPasswordDao; import io.mosip.registration.clientmanager.dao.UserTokenDao; +import io.mosip.registration.clientmanager.entity.UserBiometric; import io.mosip.registration.clientmanager.repository.ApplicantValidDocRepository; import io.mosip.registration.clientmanager.repository.AuditRepository; import io.mosip.registration.clientmanager.repository.BlocklistedWordRepository; @@ -61,6 +63,7 @@ import io.mosip.registration.clientmanager.repository.RegistrationRepository; import io.mosip.registration.clientmanager.repository.SyncJobDefRepository; import io.mosip.registration.clientmanager.repository.TemplateRepository; +import io.mosip.registration.clientmanager.repository.UserBiometricRepository; import io.mosip.registration.clientmanager.repository.UserDetailRepository; import io.mosip.registration.keymanager.dao.CACertificateStoreDao; import io.mosip.registration.keymanager.dao.KeyStoreDao; @@ -250,6 +253,12 @@ UserDetailDao providesUserDetailDao(ClientDatabase clientDatabase) { return clientDatabase.userDetailDao(); } + @Singleton + @Provides + UserBiometricDao providesUserBiometricDao(ClientDatabase clientDatabase) { + return clientDatabase.userBiometricDao(); + } + @Singleton @Provides UserPasswordDao providesUserPasswordDao(ClientDatabase clientDatabase) { @@ -372,6 +381,12 @@ UserDetailRepository provideUserDetailRepository(UserDetailDao userDetailDao, Us return new UserDetailRepository(userDetailDao, userTokenDao, userPasswordDao); } + @Provides + @Singleton + UserBiometricRepository provideUserBiometricRepository(UserBiometricDao userBiometricDao, UserDetailDao userDetailDao) { + return new UserBiometricRepository(userBiometricDao, userDetailDao); + } + @Provides @Singleton JobTransactionRepository provideJobTransactionRepository(JobTransactionDao jobTransactionDao) { diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/SessionManager.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/SessionManager.java index 0e7c3a4b8..41256c0e2 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/SessionManager.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/config/SessionManager.java @@ -21,6 +21,7 @@ public class SessionManager { public static final String IS_OPERATOR = "is_operator"; public static final String IS_DEFAULT = "is_default"; public static final String USER_NAME = "user_name"; + public static final String USER_ID = "user_id"; public static final String USER_TOKEN = "user_token"; public static final String RID = "current_rid"; public static final String USER_EMAIL = "user_email"; diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/ClientManagerError.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/ClientManagerError.java index fe0d1e450..0499dd8a5 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/ClientManagerError.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/ClientManagerError.java @@ -3,6 +3,7 @@ public enum ClientManagerError { DATE_PARSE_ERROR("MOS-REG-001", "Date parsing error"), + REG_BIOMETRIC_DTO_NULL("REG-UOS-001","Biometric Dto is mandatory field and it is missing."), SBI_DISCOVER_ERROR("MOS-REG-002", "Failed to discover SBI"); ClientManagerError(String errorCode, String errorMessage) { diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/RegistrationConstants.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/RegistrationConstants.java index 7471726e9..1a2cda9d8 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/RegistrationConstants.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/constant/RegistrationConstants.java @@ -56,6 +56,17 @@ public class RegistrationConstants { public static final String ALLOWED_BIO_ATTRIBUTES = "mosip.registration.allowed-bioattributes"; public static final String DEFAULT_APP_TYPE_CODE = "mosip.registration.default-app-type-code"; + public static final String RESPONSE = "response"; + public static final String ERRORS = "errors"; + public static final String ON_BOARD_AUTH_STATUS = "authStatus"; + public static final String USER_ON_BOARDING_THRESHOLD_NOT_MET_MSG = "USER_ON_BOARDING_THRESHOLD_NOT_MET_MSG"; + public static final String SUCCESS = "Success"; + public static final String FINGER = "FINGER"; + public static final String FACE = "FACE"; + public static final String IRIS = "IRIS"; + public static final String USER_ON_BOARDING_SUCCESS_MSG = "USER_ONBOARD_SUCCESS"; + public static final String USER_ON_BOARDING_ERROR_RESPONSE = "USER_ONBOARD_ERROR"; + //Audits public static final String REGISTRATION_SCREEN = "Registration: %s"; public static final String AGE_GROUP_CONFIG = "mosip.regproc.packet.classifier.tagging.agegroup.ranges"; diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dao/UserBiometricDao.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dao/UserBiometricDao.java new file mode 100644 index 000000000..74d78c1d7 --- /dev/null +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dao/UserBiometricDao.java @@ -0,0 +1,27 @@ +package io.mosip.registration.clientmanager.dao; + +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.OnConflictStrategy; +import androidx.room.Query; + +import java.util.List; + +import io.mosip.registration.clientmanager.entity.UserBiometric; +import io.mosip.registration.clientmanager.entity.UserDetail; + +@Dao +public interface UserBiometricDao { + + @Query("select * from user_biometric where usr_id=:id") + List findByUsrId(String id); + + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(UserBiometric userBiometric); + + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insertAllUserBiometrics(List userBiometrics); + + @Query("delete from user_biometric where usr_id=:userId") + void deleteByUsrId(String userId); +} diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dao/UserDetailDao.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dao/UserDetailDao.java index 91ac7e76e..be3517acc 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dao/UserDetailDao.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dao/UserDetailDao.java @@ -23,6 +23,9 @@ public abstract class UserDetailDao { @Insert(onConflict = OnConflictStrategy.REPLACE) public abstract void insertAllUsers(List users); + @Query("update user_detail set is_onboarded = :isOnboarded where id = :userId") + public abstract void updateUserDetail(boolean isOnboarded, String userId); + @Transaction public void truncateAndInsertAll(List users) { deleteAllUsers(); diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/http/OnboardError.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/http/OnboardError.java new file mode 100644 index 000000000..7678dedf3 --- /dev/null +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/http/OnboardError.java @@ -0,0 +1,30 @@ +package io.mosip.registration.clientmanager.dto.http; + +import com.google.gson.annotations.SerializedName; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class OnboardError { + + /** + * The error code. + */ + @SerializedName("errorCode") + private String errorCode; + /** + * The error message. + */ + @SerializedName("errorMessage") + private String errorMessage; + + public String toString() { + return "errorCode : " + errorCode + + " message : " + errorMessage; + } + +} diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/http/OnboardResponseWrapper.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/http/OnboardResponseWrapper.java new file mode 100644 index 000000000..87777bf19 --- /dev/null +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/http/OnboardResponseWrapper.java @@ -0,0 +1,23 @@ +package io.mosip.registration.clientmanager.dto.http; + +import java.util.ArrayList; +import java.util.List; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +import lombok.Data; + +@Data +public class OnboardResponseWrapper { + + private String id; + private String version; + private String responseTime; + private String transactionID; + @NotNull + @Valid + private T response; + private List errors = new ArrayList<>(); + +} diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/registration/BiometricsDto.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/registration/BiometricsDto.java index 9ce502567..4b3e16d66 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/registration/BiometricsDto.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/dto/registration/BiometricsDto.java @@ -33,6 +33,9 @@ public void setIsForceCaptured(boolean forceCaptured) { public String getBioSubType() { return bioSubType; } + public String getBioValue(){ + return bioValue; + } public String getModality(){return modality;} } diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/entity/UserBiometric.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/entity/UserBiometric.java index 027ef0253..70bf99a22 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/entity/UserBiometric.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/entity/UserBiometric.java @@ -43,5 +43,9 @@ public class UserBiometric { private Boolean isDeleted; @ColumnInfo(name = "del_dtimes") - private Timestamp delDtimes; + private Long delDtimes; + + public UserBiometric() { + + } } diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/repository/UserBiometricRepository.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/repository/UserBiometricRepository.java new file mode 100644 index 000000000..2545a1b27 --- /dev/null +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/repository/UserBiometricRepository.java @@ -0,0 +1,75 @@ +package io.mosip.registration.clientmanager.repository; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import io.mosip.registration.clientmanager.constant.Modality; +import io.mosip.registration.clientmanager.constant.RegistrationConstants; +import io.mosip.registration.clientmanager.dao.UserBiometricDao; +import io.mosip.registration.clientmanager.dao.UserDetailDao; +import io.mosip.registration.clientmanager.entity.UserBiometric; +import io.mosip.registration.clientmanager.entity.UserDetail; +import io.mosip.registration.packetmanager.cbeffutil.jaxbclasses.BIR; +import io.mosip.registration.packetmanager.cbeffutil.jaxbclasses.Biometric; + +public class UserBiometricRepository { + + private UserBiometricDao userBiometricDao; + + private UserDetailDao userDetailDao; + + @Inject + public UserBiometricRepository(UserBiometricDao userBiometricDao, UserDetailDao userDetailDao) { + this.userBiometricDao = userBiometricDao; + this.userDetailDao = userDetailDao; + } + + public String insertExtractedTemplates(List templates, String userId) { + String response = ""; + List bioMetricsList = new ArrayList<>(); + try { + for (BIR template : templates) { + UserBiometric biometrics = new UserBiometric(); + biometrics.setBioAttributeCode(getBioAttribute(template.getBdbInfo().getSubtype())); + biometrics.setBioTypeCode(getBioAttributeCode(getBioAttribute(template.getBdbInfo().getSubtype()))); + biometrics.setUsrId(userId); + biometrics.setBioTemplate(template.getBdb()); + Long qualityScore = template.getBdbInfo().getQuality().getScore(); + biometrics.setQualityScore(qualityScore.intValue()); + biometrics.setIsDeleted(false); + bioMetricsList.add(biometrics); + } + clearUserBiometrics(userId); + userBiometricDao.insertAllUserBiometrics(bioMetricsList); + response = RegistrationConstants.SUCCESS; + } catch (Exception exception) { + response = RegistrationConstants.USER_ON_BOARDING_ERROR_RESPONSE; + } + return response; + } + + public String saveOnboardStatus(String userId) { + UserDetail userDetail = userDetailDao.getUserDetail(userId); + if (userDetail != null) { + userDetailDao.updateUserDetail(true, userId); + } + return RegistrationConstants.SUCCESS; + } + + private String getBioAttribute(String subType) { + String subTypeName = (subType == null || subType.isEmpty()) ? "Face" : String.join("", subType); + String bioAttribute = Modality.getBioAttribute(subTypeName); + return (bioAttribute == null || bioAttribute.isEmpty()) ? "face" : bioAttribute; + } + + private String getBioAttributeCode(String bioAttribute) { + Biometric bioType = Biometric.getBiometricByAttribute(bioAttribute); + return bioType.getBiometricType().value(); + } + + private void clearUserBiometrics(String userId) { + userBiometricDao.deleteByUsrId(userId); + } +} diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/TemplateService.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/TemplateService.java index 5e226695c..466fe3750 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/TemplateService.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/TemplateService.java @@ -286,7 +286,6 @@ private void generateQRCode(VelocityContext velocityContext,RegistrationDto regi } } - private void setBiometricImage(Map templateValues, String key, int imagePath, Bitmap bitmap, boolean isPreview) { if (bitmap != null) { try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/UserOnboardService.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/UserOnboardService.java index 2119463ce..64f0eed0b 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/UserOnboardService.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/service/UserOnboardService.java @@ -1,47 +1,67 @@ package io.mosip.registration.clientmanager.service; import android.content.Context; +import android.content.SharedPreferences; import android.util.Log; +import android.widget.Toast; + import com.fasterxml.jackson.databind.ObjectMapper; -import io.mosip.registration.clientmanager.BuildConfig; +import io.mosip.registration.clientmanager.constant.ClientManagerError; +import io.mosip.registration.clientmanager.constant.RegistrationConstants; +import io.mosip.registration.clientmanager.R; +import io.mosip.registration.clientmanager.dto.http.OnboardError; +import io.mosip.registration.clientmanager.dto.http.OnboardResponseWrapper; import io.mosip.registration.clientmanager.dto.http.ResponseWrapper; import io.mosip.registration.clientmanager.dto.http.ServiceError; import io.mosip.registration.clientmanager.dto.registration.BiometricsDto; import io.mosip.registration.clientmanager.exception.ClientCheckedException; +import io.mosip.registration.clientmanager.repository.UserBiometricRepository; import io.mosip.registration.clientmanager.spi.AuditManagerService; +import io.mosip.registration.clientmanager.spi.RegistrationService; import io.mosip.registration.clientmanager.spi.SyncRestService; import io.mosip.registration.clientmanager.util.SyncRestUtil; import io.mosip.registration.keymanager.dto.CertificateRequestDto; import io.mosip.registration.keymanager.dto.CryptoManagerRequestDto; import io.mosip.registration.keymanager.dto.CryptoManagerResponseDto; +import io.mosip.registration.keymanager.dto.SignRequestDto; +import io.mosip.registration.keymanager.dto.SignResponseDto; import io.mosip.registration.keymanager.spi.CertificateManagerService; +import io.mosip.registration.keymanager.spi.ClientCryptoManagerService; import io.mosip.registration.keymanager.spi.CryptoManagerService; +import io.mosip.registration.packetmanager.cbeffutil.jaxbclasses.BIR; import io.mosip.registration.packetmanager.util.CryptoUtil; import io.mosip.registration.packetmanager.util.DateUtils; import io.mosip.registration.packetmanager.util.HMACUtils2; -import lombok.NonNull; +import io.mosip.registration.packetmanager.util.JsonUtils; import retrofit2.Call; +import retrofit2.Callback; import retrofit2.Response; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.inject.Inject; -import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.security.PublicKey; import java.security.cert.Certificate; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.*; +import java.util.stream.Collectors; import java.util.stream.IntStream; +import java.util.stream.Stream; + public class UserOnboardService { private static final String TAG = UserOnboardService.class.getSimpleName(); public static final String ON_BOARD_TIME_STAMP = "timestamp"; + public static final String OPERATOR_BIO_KEY = "%s_%s"; public static final String ON_BOARD_BIOMETRICS = "biometrics"; public static final String AUTH_HASH = "hash"; public static String ONBOARD_CERT_THUMBPRINT = "thumbprint"; private static final String APPLICATION_ID = "IDA"; + + private static final String APPLICATION_NAME = "Android Registration Client"; private static final String REFERENCE_ID = "INTERNAL"; public static final String CERTIFICATE = "certificate"; public static final String ID = "id"; @@ -61,8 +81,6 @@ public class UserOnboardService { public static final String SERVER_ACTIVE_PROFILE = "Staging"; public static final String TRANSACTION_ID_VALUE = "1234567890"; public static final String USER_ID_CODE = "USERID"; - - public static final String DEVICE_PROVIDER_ID = "deviceProviderID"; public static final String ON_BOARD_BIO_TYPE = "bioType"; public static final String ON_BOARD_BIO_SUB_TYPE = "bioSubType"; public static final String ON_BOARD_BIO_VALUE = "bioValue"; @@ -81,67 +99,123 @@ public class UserOnboardService { private SyncRestService syncRestService; private AuditManagerService auditManagerService; private ObjectMapper objectMapper; + private ClientCryptoManagerService clientCryptoManagerService; + SharedPreferences sharedPreferences; + public static final String USER_ID = "user_id"; + public static final String USER_TOKEN = "user_token"; + private RegistrationService registrationService; + private UserBiometricRepository userBiometricRepository; + + private static final String BIOMETRIC_KEY_PATTERN = "%s_%s_%s"; + + private List operatorBiometrics=new ArrayList<>(); + public List getOperatorBiometrics(){ + return operatorBiometrics; + } + private boolean idaResponse = false; + private String certificateDataResponse = ""; + private boolean isOnboardSuccess = false; + public boolean getIsOnboardSuccess() { + return isOnboardSuccess; + } + public String getCertificateDataResponse() { + return certificateDataResponse; + } + public boolean isIdaResponse() { + return idaResponse; + } + public void setIdaResponse(boolean idaResponse) { + this.idaResponse = idaResponse; + } @Inject public UserOnboardService(Context context, ObjectMapper objectMapper, AuditManagerService auditManagerService, CertificateManagerService certificateManagerService, - SyncRestService syncRestService, CryptoManagerService cryptoManagerService) { + SyncRestService syncRestService, CryptoManagerService cryptoManagerService, RegistrationService registrationService, UserBiometricRepository userBiometricRepository, ClientCryptoManagerService clientCryptoManagerService) { this.context = context; this.certificateManagerService = certificateManagerService; this.syncRestService = syncRestService; this.cryptoManagerService = cryptoManagerService; this.objectMapper = objectMapper; this.auditManagerService = auditManagerService; + this.registrationService = registrationService; + this.userBiometricRepository = userBiometricRepository; + this.clientCryptoManagerService = clientCryptoManagerService; + sharedPreferences = this.context.getSharedPreferences( + this.context.getString(R.string.app_name), + Context.MODE_PRIVATE); } - public boolean onboardOperator(@NonNull List biometrics) { - String userId = ""; //TODO + public void onboardOperator(List biometrics, Runnable onFinish) throws ClientCheckedException { + Log.i(TAG, "validateWithIDAuthAndSave invoked "); + + if (Objects.isNull(biometrics)) + throw new ClientCheckedException(ClientManagerError.REG_BIOMETRIC_DTO_NULL.getErrorCode(), + ClientManagerError.REG_BIOMETRIC_DTO_NULL.getErrorMessage()); + + String userId = sharedPreferences.getString(USER_ID, ""); + validateWithIDA(userId, biometrics, () -> { + if(isIdaResponse()) { + Log.i(TAG, "User onboarding success"); + isOnboardSuccess = save(biometrics, userId); + onFinish.run(); + } + }); + } + + public void validateWithIDA(String userId, List biometrics, Runnable onFinish) { + if (isIdaResponse()) { + idaResponse = true; + onFinish.run(); + } Map idaRequestMap = new LinkedHashMap<>(); idaRequestMap.put(ID, IDENTITY); idaRequestMap.put(VERSION, PACKET_SYNC_VERSION); idaRequestMap.put(REQUEST_TIME, DateUtils.formatToISOString(ZonedDateTime.now(ZoneOffset.UTC).toLocalDateTime())); idaRequestMap.put(ENV, SERVER_ACTIVE_PROFILE); - idaRequestMap.put(DOMAIN_URI, BuildConfig.BASE_URL); + idaRequestMap.put(DOMAIN_URI, "https://api-internal.qa-platform1.mosip.net"); idaRequestMap.put(TRANSACTION_ID, TRANSACTION_ID_VALUE); idaRequestMap.put(CONSENT_OBTAINED, true); idaRequestMap.put(INDIVIDUAL_ID, userId); idaRequestMap.put(INDIVIDUAL_ID_TYPE, USER_ID_CODE); idaRequestMap.put(KEY_INDEX, ""); - Map tempMap = new HashMap<>(); tempMap.put(BIO, true); idaRequestMap.put(REQUEST_AUTH, tempMap); List> listOfBiometric = new ArrayList<>(); - try { - String certificateData = getCertificate(); - Certificate certificate = this.cryptoManagerService.convertToCertificate(certificateData); - - if (Objects.nonNull(biometrics) && !biometrics.isEmpty()) { - String previousHash = HMACUtils2.digestAsPlainText("".getBytes()); - - for (BiometricsDto dto : biometrics) { - LinkedHashMap dataBlock = buildDataBlock(dto.getModality(), dto.getBioSubType(), - io.mosip.registration.keymanager.util.CryptoUtil.base64decoder.decode(dto.getBioValue()), previousHash); - dataBlock.put(ONBOARD_CERT_THUMBPRINT, CryptoUtil.encodeToURLSafeBase64(cryptoManagerService.getCertificateThumbprint(certificate))); - previousHash = (String) dataBlock.get(AUTH_HASH); - listOfBiometric.add(dataBlock); + getCertificate(() -> { + String certificateData = getCertificateDataResponse(); + try { + Certificate certificate = this.cryptoManagerService.convertToCertificate(certificateData); + if (Objects.nonNull(biometrics) && !biometrics.isEmpty()) { + String previousHash = HMACUtils2.digestAsPlainText("".getBytes()); + + for (BiometricsDto dto : biometrics) { + LinkedHashMap dataBlock = buildDataBlock(dto.getModality(), dto.getBioSubType(), + io.mosip.registration.keymanager.util.CryptoUtil.base64decoder.decode(dto.getBioValue()), previousHash); + dataBlock.put(ONBOARD_CERT_THUMBPRINT, CryptoUtil.encodeToURLSafeBase64(cryptoManagerService.getCertificateThumbprint(certificate))); + previousHash = (String) dataBlock.get(AUTH_HASH); + listOfBiometric.add(dataBlock); + } } - } - if (!listOfBiometric.isEmpty()) { - Map requestMap = new LinkedHashMap<>(); - requestMap.put(ON_BOARD_BIOMETRICS, listOfBiometric); - requestMap.put(ON_BOARD_TIME_STAMP, DateUtils.formatToISOString(DateUtils.getUTCCurrentDateTime())); - return getIdaAuthResponse(idaRequestMap, requestMap, certificate); - //TODO to save the user as successfully onboarded + if (!listOfBiometric.isEmpty()) { + Map requestMap = new LinkedHashMap<>(); + requestMap.put(ON_BOARD_BIOMETRICS, listOfBiometric); + requestMap.put(ON_BOARD_TIME_STAMP, DateUtils.formatToISOString(DateUtils.getUTCCurrentDateTime())); + getIdaAuthResponse(idaRequestMap, requestMap, certificate, () -> { + onFinish.run(); + }); + } else { + onFinish.run(); + } + } catch (Exception e) { + Log.e(TAG, e.getMessage(), e); + onFinish.run(); } - - } catch (Exception e) { - Log.e(TAG, e.getMessage(), e); - } - return false; + }); } private LinkedHashMap buildDataBlock(String bioType, String bioSubType, byte[] attributeISO, @@ -157,8 +231,8 @@ private LinkedHashMap buildDataBlock(String bioType, String bioS data.put(ON_BOARD_BIO_VALUE, splitEncryptedData.getEncryptedData()); data.put(TRANSACTION_Id, TRANSACTION_ID_VALUE); data.put(PURPOSE, PURPOSE_AUTH); - data.put(ENV, "dev.mosip.net"); //TODO - data.put(DOMAIN_URI, BuildConfig.BASE_URL); + data.put(ENV, SERVER_ACTIVE_PROFILE); + data.put(DOMAIN_URI, "https://api-internal.qa-platform1.mosip.net"); String dataBlockJsonString = this.objectMapper.writeValueAsString(data); dataBlock.put(ON_BOARD_BIO_DATA, CryptoUtil.encodeToURLSafeBase64(dataBlockJsonString.getBytes())); @@ -173,8 +247,8 @@ private LinkedHashMap buildDataBlock(String bioType, String bioS return dataBlock; } - private boolean getIdaAuthResponse(Map idaRequestMap, Map requestMap, - Certificate certificate) throws ClientCheckedException { + private void getIdaAuthResponse(Map idaRequestMap, Map requestMap, + Certificate certificate, Runnable onFinish) throws ClientCheckedException { try { PublicKey publicKey = certificate.getPublicKey(); idaRequestMap.put(ONBOARD_CERT_THUMBPRINT, CryptoUtil.encodeToURLSafeBase64(cryptoManagerService.getCertificateThumbprint(certificate))); @@ -198,44 +272,95 @@ private boolean getIdaAuthResponse(Map idaRequestMap, Map>> call = syncRestService.doOperatorAuth("test-signature", + String encodedData = io.mosip.registration.keymanager.util.CryptoUtil.base64encoder.encodeToString((JsonUtils.javaObjectToJsonString(idaRequestMap)).getBytes(StandardCharsets.UTF_8)); + SignRequestDto signRequestDto = new SignRequestDto(encodedData); + SignResponseDto signResponseDto = clientCryptoManagerService.sign(signRequestDto); + + String authToken = sharedPreferences.getString(USER_TOKEN, ""); + String signature = signResponseDto.getData(); + String cookie = String.format("Authorization=%s", authToken); + + Call>> call = syncRestService.doOperatorAuth(authToken, signature, cookie, idaRequestMap); - Response>> response = call.execute(); - if (response.isSuccessful()) { - ServiceError error = SyncRestUtil.getServiceError(response.body()); - if (error == null) { - return (Boolean) response.body().getResponse().get(ON_BOARD_AUTH_STATUS); + + call.enqueue(new Callback>>() { + @Override + public void onResponse(Call>> call, Response>> response) { + if (response.isSuccessful()) { + OnboardError error = SyncRestUtil.getServiceError(response.body()); + if (error == null || (error != null && error.getErrorCode() == null)) { + if(response.body().getResponse()!=null){ + setIdaResponse((Boolean) response.body().getResponse().get(ON_BOARD_AUTH_STATUS)); + } + + } + else{ + setIdaResponse(false); + Toast.makeText(context, error.getErrorMessage(), Toast.LENGTH_SHORT).show(); + } + onFinish.run(); + } else { + setIdaResponse(false); + Log.i("Response UserOnboard Service",response.toString()); + Toast.makeText(context, "Failed to fetch IDA Response :" + response.code(), Toast.LENGTH_LONG).show(); + onFinish.run(); + } } - } + + @Override + public void onFailure(Call>> call, Throwable t) { + t.printStackTrace(); + setIdaResponse(false); + Toast.makeText(context, "IDA Response fetch failed", Toast.LENGTH_LONG).show(); + onFinish.run(); + } + + }); + } catch (Exception e) { Log.e(TAG, e.getMessage(), e); + onFinish.run(); throw new ClientCheckedException("", e.getMessage(), e); } - return false; - } - private String getCertificate() { + private void getCertificate(Runnable onFinish) { String certData = this.certificateManagerService.getCertificate(APPLICATION_ID, REFERENCE_ID); if(certData == null) { Call>> call = syncRestService.getIDACertificate(); - try { - Response>> response = call.execute(); - if (response.isSuccessful()) { - ServiceError error = SyncRestUtil.getServiceError(response.body()); - if (error == null) { - CertificateRequestDto certificateRequestDto = new CertificateRequestDto(); - certificateRequestDto.setApplicationId(APPLICATION_ID); - certificateRequestDto.setReferenceId(REFERENCE_ID); - certificateRequestDto.setCertificateData((String) response.body().getResponse().get(CERTIFICATE)); - this.certificateManagerService.uploadOtherDomainCertificate(certificateRequestDto); + call.enqueue(new Callback>>() { + @Override + public void onResponse(Call>> call, Response>> response) { + if (response.isSuccessful()) { + ServiceError error = SyncRestUtil.getServiceError(response.body()); + if (error == null) { + CertificateRequestDto certificateRequestDto = new CertificateRequestDto(); + certificateRequestDto.setApplicationId(APPLICATION_ID); + certificateRequestDto.setReferenceId(REFERENCE_ID); + certificateRequestDto.setCertificateData((String) response.body().getResponse().get(CERTIFICATE)); + certificateManagerService.uploadOtherDomainCertificate(certificateRequestDto); + } + certificateDataResponse = certificateManagerService.getCertificate(APPLICATION_ID, REFERENCE_ID); + onFinish.run(); + } else{ + Log.i("Response UserOnboard Service",response.toString()); + Toast.makeText(context, "Failed to fetch IDA Internal certificate :" + response.code(), Toast.LENGTH_LONG).show(); + onFinish.run(); } } - } catch (IOException e) { - Log.e(TAG, "Failed to fetch IDA Internal certificate", e); - } + + @Override + public void onFailure(Call>> call, Throwable t) { + t.printStackTrace(); + Toast.makeText(context, "IDA Internal Certificate fetch failed", Toast.LENGTH_LONG).show(); + onFinish.run(); + } + }); + + } else { + certificateDataResponse = certData; + onFinish.run(); } - return this.certificateManagerService.getCertificate(APPLICATION_ID, REFERENCE_ID); } private synchronized SplitEncryptedData getSessionKey(Map requestMap, byte[] data) throws Exception { @@ -401,4 +526,64 @@ public String getEncryptedSessionKey() { } } + + private boolean save(List biometrics, String userId) { + Log.i(TAG, "Entering save method"); + String onBoardingResponse = ""; + try { + List fingerprintsList = getBiometricsByModality(RegistrationConstants.FINGER, + biometrics); + List irisList = getBiometricsByModality(RegistrationConstants.IRIS, biometrics); + List face = getBiometricsByModality(RegistrationConstants.FACE, biometrics); + + List fpTemplates = getExtractedTemplates(fingerprintsList); + List irisTemplates = getExtractedTemplates(irisList); + List faceTemplates = getExtractedTemplates(face); + + List templates = Stream.of(fpTemplates, irisTemplates, faceTemplates).flatMap(Collection::stream) + .collect(Collectors.toList()); + + onBoardingResponse = userBiometricRepository.insertExtractedTemplates(templates, userId); + if (onBoardingResponse.equalsIgnoreCase(RegistrationConstants.SUCCESS)) { + Log.i(TAG, "operator details inserted"); + if ((RegistrationConstants.SUCCESS).equalsIgnoreCase(userBiometricRepository.saveOnboardStatus(userId))) { + Log.i(TAG, "center user machine details inserted"); + return true; + } + } + } catch (Exception exception) { + Log.e(TAG, "Exception while saving operator biometrics", exception); + return false; + } + return false; + } + + private List getExtractedTemplates(List biometrics) { + List templates = new ArrayList<>(); + if (biometrics != null && !biometrics.isEmpty()) { + List birList = new ArrayList<>(); + for (BiometricsDto biometricsDto : biometrics) { + try { + BIR bir = registrationService.buildBIR(biometricsDto); + Log.i(TAG, "Adding bir"); + birList.add(bir); + } catch (Exception e){ + Log.e(TAG, "Error in adding BIR: " + e.getMessage()); + } + } + return birList; + //TODO - Template extration logic to be done when SDK for android is implemented +// templates = bioAPIFactory +// .getBioProvider(BiometricType.fromValue(birList.get(0).getBdbInfo().getType().get(0).value()), +// BiometricFunction.EXTRACT) +// .extractTemplate(birList, null); + } + return templates; + } + + private List getBiometricsByModality(String modality, List biometrics) { + return biometrics.stream().filter(dto -> dto.getModality().toLowerCase().contains(modality.toLowerCase())) + .collect(Collectors.toList()); + } + } diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/spi/RegistrationService.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/spi/RegistrationService.java index 0a91c442a..c044a6117 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/spi/RegistrationService.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/spi/RegistrationService.java @@ -1,7 +1,9 @@ package io.mosip.registration.clientmanager.spi; +import io.mosip.registration.clientmanager.dto.registration.BiometricsDto; import io.mosip.registration.clientmanager.dto.registration.RegistrationDto; import io.mosip.registration.clientmanager.entity.Registration; +import io.mosip.registration.packetmanager.cbeffutil.jaxbclasses.BIR; import java.util.List; @@ -18,4 +20,6 @@ public interface RegistrationService { void submitRegistrationDto(String makerName) throws Exception; void clearRegistration(); + + BIR buildBIR(BiometricsDto biometricsDto); } diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/spi/SyncRestService.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/spi/SyncRestService.java index 55caa8a2e..c03ae89fd 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/spi/SyncRestService.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/spi/SyncRestService.java @@ -74,7 +74,9 @@ Call> getCACertificates(@Query("lastup Call>> getIDACertificate(); @POST("/registrationprocessor/v1/registrationstatus/auth") - Call>> doOperatorAuth(@Header("signature") String signature, + Call>> doOperatorAuth(@Header("Authorization") String authToken, + @Header("Signature") String signature, + @Header("Cookie") String cookie, @Body Map requestMap); @GET Call downloadScript(@Url String url, diff --git a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/util/SyncRestUtil.java b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/util/SyncRestUtil.java index 1d27c97ce..7f4d6019f 100644 --- a/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/util/SyncRestUtil.java +++ b/android/clientmanager/src/main/java/io/mosip/registration/clientmanager/util/SyncRestUtil.java @@ -2,6 +2,9 @@ import android.util.Log; import com.fasterxml.jackson.core.JsonProcessingException; + +import io.mosip.registration.clientmanager.dto.http.OnboardError; +import io.mosip.registration.clientmanager.dto.http.OnboardResponseWrapper; import io.mosip.registration.clientmanager.dto.http.RegProcResponseWrapper; import io.mosip.registration.clientmanager.dto.http.RequestWrapper; import io.mosip.registration.clientmanager.dto.http.ResponseWrapper; @@ -47,6 +50,18 @@ public static ServiceError getServiceError(ResponseWrapper wrapper) { return (ServiceError) wrapper.getErrors().get(0); } + public static OnboardError getServiceError(OnboardResponseWrapper wrapper) { + if((wrapper.getErrors() == null || wrapper.getErrors().isEmpty()) && wrapper.getResponse() != null) + return null; + + try { + Log.i(TAG, JsonUtils.javaObjectToJsonString(wrapper.getErrors())); + } catch (JsonProcessingException e) { + Log.e(TAG, "error parsing service error", e); + } + return (OnboardError) wrapper.getErrors().get(0); + } + public static ServiceError getServiceError(RegProcResponseWrapper wrapper) { if((wrapper.getErrors() == null || wrapper.getErrors().isEmpty()) && wrapper.getResponse() != null) return null; diff --git a/android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/BDBInfo.java b/android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/BDBInfo.java index 41cae979a..528b46476 100644 --- a/android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/BDBInfo.java +++ b/android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/BDBInfo.java @@ -1,12 +1,14 @@ package io.mosip.registration.packetmanager.cbeffutil.jaxbclasses; import io.mosip.registration.packetmanager.dto.PacketWriter.BiometricType; +import lombok.Data; + import org.simpleframework.xml.Element; import org.simpleframework.xml.ElementList; import java.time.LocalDateTime; import java.util.List; - +@Data public class BDBInfo { @Element(name = "ChallengeResponse", required = false) diff --git a/android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/Biometric.java b/android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/Biometric.java new file mode 100644 index 000000000..3be84c3d0 --- /dev/null +++ b/android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/Biometric.java @@ -0,0 +1,145 @@ +package io.mosip.registration.packetmanager.cbeffutil.jaxbclasses; + +import java.util.ArrayList; +import java.util.List; + +import io.mosip.registration.packetmanager.dto.PacketWriter.BiometricType; + +public enum Biometric { + + LEFT_INDEX("FINGERPRINT_SLAB_LEFT", "Left Slab", "leftIndex", BiometricType.FINGER, "LF_INDEX"), + LEFT_MIDDLE("FINGERPRINT_SLAB_LEFT", "Left Slab", "leftMiddle", BiometricType.FINGER, "LF_MIDDLE"), + LEFT_RING("FINGERPRINT_SLAB_LEFT", "Left Slab", "leftRing", BiometricType.FINGER, "LF_RING"), + LEFT_LITTLE("FINGERPRINT_SLAB_LEFT", "Left Slab", "leftLittle", BiometricType.FINGER, "LF_LITTLE"), + RIGHT_INDEX("FINGERPRINT_SLAB_RIGHT", "Right Slab", "rightIndex", BiometricType.FINGER, "RF_INDEX"), + RIGHT_MIDDLE("FINGERPRINT_SLAB_RIGHT", "Right Slab", "rightMiddle", BiometricType.FINGER, "RF_MIDDLE"), + RIGHT_RING("FINGERPRINT_SLAB_RIGHT", "Right Slab", "rightRing", BiometricType.FINGER, "RF_RING"), + RIGHT_LITTLE("FINGERPRINT_SLAB_RIGHT", "Right Slab", "rightLittle", BiometricType.FINGER, "RF_LITTLE"), + LEFT_THUMB("FINGERPRINT_SLAB_THUMBS", "Thumbs", "leftThumb", BiometricType.FINGER, "LF_THUMB"), + RIGHT_THUMB("FINGERPRINT_SLAB_THUMBS", "Thumbs", "rightThumb", BiometricType.FINGER, "RF_THUMB"), + RIGHT_IRIS("IRIS_DOUBLE", "Iris", "rightEye", BiometricType.IRIS, "R_IRIS"), + LEFT_IRIS("IRIS_DOUBLE", "Iris", "leftEye", BiometricType.IRIS, "L_IRIS"), + FACE("FACE_FULL FACE", "Face", "face", BiometricType.FACE, "FACE"), + EXCEPTION("FACE_FULL FACE", "ExceptionPhoto", "unknown", BiometricType.EXCEPTION_PHOTO, "EXCEPTION_PHOTO"); + + Biometric(String modalityName, String modalityShortName, String attributeName, BiometricType biometricType, + String mdmConstant) { + this.modalityName = modalityName; + this.setModalityShortName(modalityShortName); + this.attributeName = attributeName; + this.biometricType = biometricType; + this.mdmConstant = mdmConstant; + } + + private String modalityName; + private String modalityShortName; + private String attributeName; + private BiometricType biometricType; + private String mdmConstant; + + public String getModalityName() { + return modalityName; + } + public void setModalityName(String modalityName) { + this.modalityName = modalityName; + } + public String getAttributeName() { + return attributeName; + } + public void setAttributes(String attributeName) { + this.attributeName = attributeName; + } + + public BiometricType getBiometricType() { + return biometricType; + } + + public void setBiometricType(BiometricType biometricType) { + this.biometricType = biometricType; + } + + public String getModalityShortName() { + return modalityShortName; + } + public void setModalityShortName(String modalityShortName) { + this.modalityShortName = modalityShortName; + } + public static List getDefaultAttributes(String modalityName) { + List list = new ArrayList<>(); + for(Biometric biometric : Biometric.values()) { + if(biometric.getModalityName().equalsIgnoreCase(modalityName) || + biometric.getModalityShortName().equalsIgnoreCase(modalityName)) + list.add(biometric.getAttributeName()); + } + return list; + } + + public static String getModalityNameByAttribute(String attributeName) { + String modalityName = null; + for(Biometric biometric : Biometric.values()) { + if(biometric.getAttributeName().equalsIgnoreCase(attributeName)) { + modalityName = biometric.getModalityName(); + break; + } + } + return modalityName; + } + + public static BiometricType getSingleTypeByAttribute(String attributeName) { + BiometricType modalityName = null; + for(Biometric biometric : Biometric.values()) { + if(biometric.getAttributeName().equalsIgnoreCase(attributeName)) { + modalityName = biometric.getBiometricType(); + break; + } + } + return modalityName; + } + + public static Biometric getBiometricByAttribute(String attributeName) { + Biometric constant = null; + for(Biometric biometric : Biometric.values()) { + if(biometric.getMdmConstant().equalsIgnoreCase(attributeName) || + biometric.getAttributeName().equalsIgnoreCase(attributeName)) { + constant = biometric; + break; + } + } + return constant; + } + + public static Biometric getBiometricByMDMConstant(String mdmConstant) { + Biometric constant = null; + for(Biometric biometric : Biometric.values()) { + if(biometric.getMdmConstant().equalsIgnoreCase(mdmConstant)) { + constant = biometric; + break; + } + } + return constant; + } + + public static long getFormatType(BiometricType biometricType) { + long format = 0; + switch (biometricType) { + case FINGER: + format = CbeffConstant.FORMAT_TYPE_FINGER; + break; + + case EXCEPTION_PHOTO: + case FACE: + format = CbeffConstant.FORMAT_TYPE_FACE; + break; + case IRIS: + format = CbeffConstant.FORMAT_TYPE_IRIS; + break; + } + return format; + } + public String getMdmConstant() { + return mdmConstant; + } + public void setMdsConstant(String mdmConstant) { + this.mdmConstant = mdmConstant; + } +} diff --git a/android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/CbeffConstant.java b/android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/CbeffConstant.java new file mode 100644 index 000000000..2b283e149 --- /dev/null +++ b/android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/CbeffConstant.java @@ -0,0 +1,25 @@ +package io.mosip.registration.packetmanager.cbeffutil.jaxbclasses; + +public class CbeffConstant { + + public static final long FORMAT_OWNER = 257; + + // Format Type + + public static final long FORMAT_TYPE_IRIS = 9; + + public static final long FORMAT_TYPE_FACE = 8; + + public static final long FORMAT_TYPE_FINGER = 7; + + public static final long FORMAT_TYPE_FINGER_MINUTIAE = 2; + + // Format Identifier + + public static final int FINGER_FORMAT_IDENTIFIER = 0x46495200; + + public static final int IRIS_FORMAT_IDENTIFIER = 0x49495200; + + public static final int FACE_FORMAT_IDENTIFIER = 0x46495200; + +} diff --git a/android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/QualityType.java b/android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/QualityType.java index dee226fad..056d530b2 100644 --- a/android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/QualityType.java +++ b/android/packetmanager/src/main/java/io/mosip/registration/packetmanager/cbeffutil/jaxbclasses/QualityType.java @@ -4,7 +4,10 @@ import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; +import lombok.Data; + @Root +@Data public class QualityType { @Element(name = "Algorithm") diff --git a/androidReg-clientTest/target/classes/DesiredCapabilities.json b/androidReg-clientTest/target/classes/DesiredCapabilities.json new file mode 100644 index 000000000..e538aff4a --- /dev/null +++ b/androidReg-clientTest/target/classes/DesiredCapabilities.json @@ -0,0 +1,17 @@ +[ + { + "name": "androidDevice", + "caps": { + "appium:udid": "RZ8T10YV8GJ", + "appium:automationName": "UiAutomator2", + "appium:app": "D:/app-release.apk", + "platformName": "android", + "appium:appPackage": "io.mosip.registration_client", + "appium:appActivity": "io.mosip.registration_client.MainActivity", + "appium:noReset": true, + "appium:autoGrantPermissions": true, + "appium:shouldTerminateApp": true, + "appium:noSign": true + } + } +] \ No newline at end of file diff --git a/androidReg-clientTest/target/classes/config.properties b/androidReg-clientTest/target/classes/config.properties new file mode 100644 index 000000000..959f514f7 --- /dev/null +++ b/androidReg-clientTest/target/classes/config.properties @@ -0,0 +1,5 @@ +ipAddress=127.0.0.1 +nodePath=C:/Program Files/nodejs/node +appiumServerExecutable=C:/Users/jayesh.kharode/AppData/Roaming/npm/node_modules/appium/build/lib/main.js +appiumLogFilePath=report/appiumLogs.txt +startAppiumServer=true \ No newline at end of file diff --git a/assets/svg/success_message_icon.svg b/assets/svg/success_message_icon.svg new file mode 100644 index 000000000..500f9eed5 --- /dev/null +++ b/assets/svg/success_message_icon.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/provider/global_provider.dart b/lib/provider/global_provider.dart index fc7bace50..f4d751768 100644 --- a/lib/provider/global_provider.dart +++ b/lib/provider/global_provider.dart @@ -48,6 +48,7 @@ class GlobalProvider with ChangeNotifier { int _htmlBoxTabIndex = 0; List _chosenLang = []; + String _operatorOnboardingAttributes=""; Map _languageMap = { 'English': true, 'Arabic': false, @@ -122,6 +123,12 @@ class GlobalProvider with ChangeNotifier { Map get machineDetails => _machineDetails; String get regId => _regId; + String get operatorOnboardingAttributes => _operatorOnboardingAttributes; + set operatorOnboardingAttributes(String value) { + _operatorOnboardingAttributes = value; + notifyListeners(); + } + Map get mvelValues => _mvelValues; setRegId(String value) { @@ -342,7 +349,7 @@ class GlobalProvider with ChangeNotifier { } else { commitId = head; } - } catch (e) { + } catch(e) { debugPrint("Failed fetching git info: $e"); } diff --git a/lib/ui/login_page.dart b/lib/ui/login_page.dart index af3e135c0..b9535b955 100644 --- a/lib/ui/login_page.dart +++ b/lib/ui/login_page.dart @@ -15,6 +15,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:provider/provider.dart'; import 'package:registration_client/main.dart'; + import 'package:registration_client/pigeon/user_pigeon.dart'; import 'package:registration_client/provider/auth_provider.dart'; @@ -128,6 +129,68 @@ class _LoginPageState extends State with WidgetsBindingObserver { } } + _saveConsentScreenHeaders() async { + for (var header in lang) { + await _saveHeader("consentScreenName_$header", + AppLocalizations.of(context)!.consentScreenName(header)); + } + } + + _saveDemographicScreenHeaders() async { + for (var header in lang) { + await _saveHeader("demographicsScreenName_$header", + AppLocalizations.of(context)!.demographicsScreenName(header)); + } + } + + _saveDocumentScreenHeaders() async { + for (var header in lang) { + await _saveHeader("documentsScreenName_$header", + AppLocalizations.of(context)!.documentsScreenName(header)); + } + } + + _saveBiometricScreenHeaders() async { + for (var header in lang) { + await _saveHeader("biometricsScreenName_$header", + AppLocalizations.of(context)!.biometricsScreenName(header)); + } + } + + _saveHeader(String id, String value) async { + await context + .read() + .saveScreenHeaderToGlobalParam(id, value); + } + + _initializeBiometricThresholdData() async { + await context.read().getThresholdValues(); + } + + _initializeMachineData() async { + await context.read().setMachineDetails(); + } + + // _initializeAppLanguageData() async { + // await context.read().initializeLanguageDataList(); + // } + + _initializeLocationHierarchy() async { + await context.read().initializeLocationHierarchyMap(); + } + + _loginPageLoadedAudit() async { + await context + .read() + .getAudit("REG-LOAD-001", "REG-MOD-101"); + } + + _longPressLogoAudit() async { + await context + .read() + .getAudit("REG-AUTH-002", "REG-MOD-101"); + } + @override Widget build(BuildContext context) { isMobile = MediaQuery.of(context).orientation == Orientation.portrait; @@ -258,6 +321,21 @@ class _LoginPageState extends State with WidgetsBindingObserver { ); } + _onLoginButtonPressed() async { + await _getLoginAction(); + await _initializeBiometricThresholdData(); + } + + _authenticateUser(bool isConnected) async { + await context + .read() + .authenticateUser(username, password, isConnected); + } + + _getIsConnected() { + return context.read().isConnected; + } + _getLoginAction() async { FocusManager.instance.primaryFocus?.unfocus(); if (password.isEmpty) { diff --git a/lib/ui/onboard/home_page.dart b/lib/ui/onboard/home_page.dart index 79b35ff05..d0690087e 100644 --- a/lib/ui/onboard/home_page.dart +++ b/lib/ui/onboard/home_page.dart @@ -13,12 +13,15 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:registration_client/model/process.dart'; +import 'package:registration_client/pigeon/biometrics_pigeon.dart'; import 'package:registration_client/pigeon/dynamic_response_pigeon.dart'; import 'package:registration_client/provider/connectivity_provider.dart'; import 'package:registration_client/provider/global_provider.dart'; import 'package:registration_client/provider/sync_provider.dart'; import 'package:registration_client/ui/onboard/portrait/mobile_home_page.dart'; +import 'package:registration_client/ui/onboard/widgets/operator_onboarding_biometrics_capture_control.dart'; +// import 'package:registration_client/ui/onboard/widgets/home_page_card.dart'; import 'package:registration_client/ui/process_ui/widgets/language_selector.dart'; @@ -153,8 +156,15 @@ class _HomePageState extends State { "icon": SvgPicture.asset( "assets/svg/Updating Operator Biometrics.svg", ), - "title": appLocalizations.update_operator_biomterics, - "onTap": () {}, + "title": AppLocalizations.of(context)!.update_operator_biomterics, + "onTap": (context) async { + await BiometricsApi().startOperatorOnboarding(); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + OperatorOnboardingBiometricsCaptureControl())); + }, "subtitle": "Last updated on Wednesday 12 Apr, 11:20PM" }, { diff --git a/lib/ui/onboard/onboarding_page.dart b/lib/ui/onboard/onboarding_page.dart index 2e5bd695a..5723c1aa6 100644 --- a/lib/ui/onboard/onboarding_page.dart +++ b/lib/ui/onboard/onboarding_page.dart @@ -8,8 +8,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:provider/provider.dart'; +import 'package:registration_client/pigeon/biometrics_pigeon.dart'; import 'package:registration_client/provider/auth_provider.dart'; import 'package:registration_client/provider/global_provider.dart'; +import 'package:registration_client/ui/onboard/widgets/operator_onboarding_biometrics_capture_control.dart'; import 'package:registration_client/utils/app_config.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -71,7 +73,7 @@ class OnboardingPage extends StatelessWidget { Text( "${appLocalizations.hello}, ", style: TextStyle( - fontSize: isMobileSize ? 28 : 36, + fontSize: isMobileSize ? 28.h : 36.h, color: appWhite, ), ), @@ -100,8 +102,15 @@ class OnboardingPage extends StatelessWidget { height: 65.h, ), _getButton( - title: appLocalizations.get_onboard, - onTap: () {}, + title: AppLocalizations.of(context)!.get_onboard, + onTap: () async{ + await BiometricsApi().startOperatorOnboarding(); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + OperatorOnboardingBiometricsCaptureControl())); + }, color: appWhite, fontColor: appSolidPrimary, ), diff --git a/lib/ui/onboard/portrait/operational_tasks.dart b/lib/ui/onboard/portrait/operational_tasks.dart index f5df8ee32..7f22f67f7 100644 --- a/lib/ui/onboard/portrait/operational_tasks.dart +++ b/lib/ui/onboard/portrait/operational_tasks.dart @@ -175,15 +175,18 @@ class _OperationalTasksState extends State { index: index, icon: widget.operationalTasks[index]["icon"], title: widget.operationalTasks[index]["title"] as String, - ontap: () => - widget.operationalTasks[index]["onTap"](context), + ontap: () async { + return widget.operationalTasks[index]["onTap"](context); + }, ), ) : TaskCard( index: index, icon: widget.operationalTasks[index]["icon"], title: widget.operationalTasks[index]["title"] as String, - ontap: () => widget.operationalTasks[index]["onTap"](context), + ontap: () { + return widget.operationalTasks[index]["onTap"](context); + }, subtitle: widget.operationalTasks[index]["subtitle"], ); }, diff --git a/lib/ui/onboard/portrait/task_card.dart b/lib/ui/onboard/portrait/task_card.dart index 49fdb52b6..9e88ace2c 100644 --- a/lib/ui/onboard/portrait/task_card.dart +++ b/lib/ui/onboard/portrait/task_card.dart @@ -22,7 +22,7 @@ class TaskCard extends StatefulWidget { final Widget icon; final String title; final int index; - final VoidCallback ontap; + final Function ontap; final String subtitle; @override @@ -42,7 +42,7 @@ class _TaskCardState extends State { child: SizedBox( height: 110.h, child: ListTile( - onTap: widget.ontap, + onTap: (){widget.ontap();}, contentPadding: EdgeInsets.only( top: 15.h, bottom: 17.h, diff --git a/lib/ui/onboard/widgets/operator_biometric_capture_scan_block_view.dart b/lib/ui/onboard/widgets/operator_biometric_capture_scan_block_view.dart new file mode 100644 index 000000000..6e00016e0 --- /dev/null +++ b/lib/ui/onboard/widgets/operator_biometric_capture_scan_block_view.dart @@ -0,0 +1,2071 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:percent_indicator/linear_percent_indicator.dart'; +import 'package:provider/provider.dart'; +import 'package:registration_client/model/biometric_attribute_data.dart'; +import 'package:registration_client/model/biometrics_dto.dart'; +import 'package:registration_client/pigeon/biometrics_pigeon.dart'; +// import 'package:registration_client/pigeon/biometrics_pigeon.dart'; + +import 'package:registration_client/provider/biometric_capture_control_provider.dart'; +import 'package:registration_client/provider/registration_task_provider.dart'; +import 'package:registration_client/utils/app_config.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +class OperatorBiometricCaptureScanBlockView extends StatefulWidget { + const OperatorBiometricCaptureScanBlockView({super.key}); + + @override + State createState() => + _OperatorBiometricCaptureScanBlockViewState(); +} + +class _OperatorBiometricCaptureScanBlockViewState + extends State { + bool isPortrait = true; + + @override + void initState() { + super.initState(); + context + .read() + .biometricCaptureScanBlockTabIndex = 1; + } + + setInitialState() { + if (context.read().biometricAttribute == + "Iris") { + biometricAttributeData = + context.read().iris; + } + if (context.read().biometricAttribute == + "Right Hand") { + biometricAttributeData = + context.read().rightHand; + } + if (context.read().biometricAttribute == + "Left Hand") { + biometricAttributeData = + context.read().leftHand; + } + if (context.read().biometricAttribute == + "Thumbs") { + biometricAttributeData = + context.read().thumbs; + } + if (context.read().biometricAttribute == + "Face") { + biometricAttributeData = + context.read().face; + } + if (context.read().biometricAttribute == + "Exception") { + biometricAttributeData = + context.read().exception; + } + } + + _getNextElement(List list, String title) { + for (int i = 0; i < list.length; i++) { + if (list[i] == title) { + if (i < list.length - 1) { + return list[i + 1]; + } else { + return null; + } + } + } + } + + _showCustomAlert(List temp) { + return showDialog( + context: context, + builder: (BuildContext context) => SingleChildScrollView( + child: AlertDialog( + content: SizedBox( + height: (isMobileSize) ? 310.h : 510.h, + width: 760.w, + child: Column( + children: [ + const SizedBox( + height: 26, + ), + Row( + children: [ + const Spacer(), + const SizedBox( + width: 28, + ), + Text( + "${biometricAttributeData.title.replaceAll(" ", "")} ${AppLocalizations.of(context)!.capture}", + style: Theme.of(context).textTheme.bodyLarge?.copyWith( + fontSize: 28, fontWeight: bold, color: blackShade1), + ), + const Spacer(), + IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: Icon( + Icons.close, + color: blackShade1, + weight: 25, + size: 28, + )), + ], + ), + Divider( + height: 66, + thickness: 1, + color: secondaryColors.elementAt(22), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ...temp.map( + (e) => Image.memory( + e!, + height: (isMobileSize) ? 130.h : 260.h, + ), + ), + ], + ), + // Divider( + // height: 82, + // thickness: 1, + // color: secondaryColors.elementAt(22), + // ), + // Container( + // height: 96, + // decoration: BoxDecoration( + // color: secondaryColors.elementAt(23), + // borderRadius: BorderRadius.circular(6)), + // child: Center( + // child: Text( + // "${biometricAttributeData.noOfCapturesAllowed - currentAttemptNo} ${AppLocalizations.of(context)!.attempts_left}", + // style: TextStyle( + // fontSize: 25, + // fontWeight: semiBold, + // color: secondaryColors.elementAt(24)), + // ), + // ), + // ) + ], + ), + ), + ), + ), + ); + } + + _showScanDialogBox(List temp) async { + // int currentAttemptNo = await BiometricsApi().getBioAttempt( + // "operatorBiometrics", biometricAttributeData.title.replaceAll(" ", "")); + _showCustomAlert(temp); + } + + Widget _scanBlock() { + return Column( + children: [ + Container( + decoration: BoxDecoration( + color: pureWhite, + border: Border.all(color: secondaryColors.elementAt(14), width: 1), + ), + height: 353.h, + width: (isPortrait) ? double.infinity : 760.w, + child: (biometricAttributeData.isScanned == false) + ? Directionality( + textDirection: TextDirection.ltr, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ...biometricAttributeData.listofImages + .map((e) => SvgPicture.asset( + "$e", + height: (isMobileSize) + ? biometricAttributeData.imageHeightMobile.h + : biometricAttributeData + .imageHeightTablet.h, + fit: BoxFit.fitHeight, + )) + ], + ), + ) + : Directionality( + textDirection: TextDirection.ltr, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ...biometricAttributeData.listofImages + .map((e) => Image.memory( + e, + height: (isMobileSize) ? 70.h : 130.h, + )) + ], + ), + ), + ), + const SizedBox( + height: 30, + ), + Container( + decoration: BoxDecoration( + color: pureWhite, + border: Border.all(color: secondaryColors.elementAt(14), width: 1), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox( + width: double.infinity, + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 20, 0, 18), + child: Text( + AppLocalizations.of(context)!.quality, + style: TextStyle( + fontSize: 24, color: blackShade1, fontWeight: semiBold), + ), + ), + Text( + "${AppLocalizations.of(context)!.threshold} ${biometricAttributeData.thresholdPercentage}%", + style: Theme.of(context).textTheme.bodyLarge?.copyWith( + fontSize: 23, + fontWeight: regular, + color: secondaryColors.elementAt(1), + ), + ), + SizedBox( + height: 21.h, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + LinearPercentIndicator( + width: (isMobileSize) ? 250.w : 450.w, + lineHeight: 15.4, + percent: biometricAttributeData.qualityPercentage / 100, + backgroundColor: Colors.grey, + progressColor: + (biometricAttributeData.qualityPercentage.toInt() < + int.parse( + biometricAttributeData.thresholdPercentage)) + ? secondaryColors.elementAt(26) + : secondaryColors.elementAt(11), + ), + SizedBox( + width: (isMobileSize) ? 20.w : 43.w, + ), + Text( + "${biometricAttributeData.qualityPercentage.toInt()}%", + style: Theme.of(context).textTheme.bodyLarge?.copyWith( + fontSize: 23, + fontWeight: semiBold, + color: secondaryColors.elementAt(1), + ), + ), + ], + ), + SizedBox( + height: 26.h, + ), + SizedBox( + height: 18.h, + ), + ], + ), + ), + const SizedBox( + height: 45, + ), + ElevatedButton.icon( + onPressed: () async { + if (biometricAttributeData.exceptions.contains(false)) { + List tempImageList = []; + await BiometricsApi().invokeDiscoverSbi("operatorBiometrics", + biometricAttributeData.title.replaceAll(" ", "")); + await BiometricsApi() + .getBestBiometrics("operatorBiometrics", + biometricAttributeData.title.replaceAll(" ", "")) + .then((value) {}); + await BiometricsApi() + .extractImageValues("operatorBiometrics", + biometricAttributeData.title.replaceAll(" ", "")) + .then((value) { + tempImageList = value; + }); + + biometricAttributeData.listOfBiometricsDto.clear(); + // await BiometricsApi().incrementBioAttempt("operatorBiometrics", + // biometricAttributeData.title.replaceAll(" ", "")); + // biometricAttributeData.attemptNo = await BiometricsApi() + // .getBioAttempt("operatorBiometrics", + // biometricAttributeData.title.replaceAll(" ", "")); + await BiometricsApi() + .getBestBiometrics("operatorBiometrics", + biometricAttributeData.title.replaceAll(" ", "")) + .then((value) async { + for (var e in value) { + biometricAttributeData.listOfBiometricsDto.add( + BiometricsDto.fromJson( + json.decode(e!), + ), + ); + } + }); + biometricAttributeData.qualityPercentage = + biometricCaptureControlProvider + .avgScore(biometricAttributeData.listOfBiometricsDto); + await BiometricsApi() + .extractImageValues("operatorBiometrics", + biometricAttributeData.title.replaceAll(" ", "")) + .then((value) { + biometricAttributeData.listofImages = value; + }); + biometricAttributeData.isScanned = true; + // generateList("${widget.field.id}", biometricAttributeData); + _showScanDialogBox(tempImageList); + setState(() {}); + // } + } + }, + icon: Icon( + Icons.crop_free, + color: pureWhite, + size: 36.6, + ), + label: Text( + AppLocalizations.of(context)!.scan, + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith(fontSize: 27, fontWeight: bold, color: pureWhite), + ), + style: OutlinedButton.styleFrom( + padding: (isMobileSize) + ? const EdgeInsets.symmetric(horizontal: 35, vertical: 25) + : const EdgeInsets.symmetric(horizontal: 46, vertical: 34), + backgroundColor: + ((biometricAttributeData.exceptions.contains(false)) + ? solidPrimary + : secondaryColors.elementAt(22)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), + ), + ), + ), + SizedBox( + height: 20.h, + ), + ], + ); + } + + Widget _returnExceptionImage() { + if (biometricAttributeData.title == "Iris") { + return SizedBox( + height: 300, + child: Directionality( + textDirection: TextDirection.ltr, + child: + Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ + Stack( + children: [ + SizedBox( + height: (isMobileSize) ? 100.h : 150.h, + width: (isMobileSize) ? 165.w : 250.w, + child: SvgPicture.asset( + "assets/svg/Left Eye.svg", + fit: BoxFit.fitHeight, + ), + ), + Positioned( + top: 10, + left: 10, + child: SizedBox( + height: (isMobileSize) ? 100.h : 150.h, + width: (isMobileSize) ? 165.w : 250.w, + child: InkWell( + onTap: () async { + if (!(biometricAttributeData.exceptions[0]) == true) { + await BiometricsApi().addBioException( + "operatorBiometrics", "Iris", "leftEye"); + biometricAttributeData.isScanned = false; + biometricAttributeData.attemptNo = 0; + biometricAttributeData.listofImages = [ + "assets/svg/Left Eye.svg", + "assets/svg/Right Eye.svg" + ]; + biometricAttributeData.listOfBiometricsDto = []; + biometricAttributeData.qualityPercentage = 0.0; + biometricAttributeData.thresholdPercentage = "0"; + } else { + await BiometricsApi().removeBioException( + "operatorBiometrics", "Iris", "leftEye"); + biometricAttributeData.isScanned = false; + biometricAttributeData.attemptNo = 0; + biometricAttributeData.listofImages = [ + "assets/svg/Left Eye.svg", + "assets/svg/Right Eye.svg" + ]; + biometricAttributeData.listOfBiometricsDto = []; + biometricAttributeData.qualityPercentage = 0.0; + biometricAttributeData.thresholdPercentage = "0"; + } + biometricAttributeData.exceptions[0] = + !(biometricAttributeData.exceptions[0]); + + if (biometricAttributeData.exceptions + .contains(true)) { + if (biometricAttributeData.exceptionType.isEmpty) { + biometricAttributeData.exceptionType = + "Permanent"; + } + } + if (!biometricAttributeData.exceptions + .contains(true)) { + biometricAttributeData.exceptionType = ""; + } + setState(() {}); + }, + child: SvgPicture.asset( + "assets/svg/left_iris.svg", + fit: BoxFit.fitHeight, + color: (biometricAttributeData.exceptions[0] == true) + ? secondaryColors.elementAt(25) + : Colors.transparent, + ), + )), + ), + ], + ), + Stack( + children: [ + SizedBox( + height: (isMobileSize) ? 100.h : 150.h, + width: (isMobileSize) ? 165.w : 250.w, + child: SvgPicture.asset( + "assets/svg/Right Eye.svg", + fit: BoxFit.fitHeight, + ), + ), + Positioned( + top: 10, + right: 10, + child: SizedBox( + height: (isMobileSize) ? 100.h : 150.h, + width: (isMobileSize) ? 165.w : 250.w, + child: InkWell( + onTap: () async { + if (!(biometricAttributeData.exceptions[1]) == true) { + await BiometricsApi().addBioException( + "operatorBiometrics", "Iris", "rightEye"); + biometricAttributeData.isScanned = false; + biometricAttributeData.attemptNo = 0; + biometricAttributeData.listofImages = [ + "assets/svg/Left Eye.svg", + "assets/svg/Right Eye.svg" + ]; + biometricAttributeData.listOfBiometricsDto = []; + biometricAttributeData.qualityPercentage = 0.0; + biometricAttributeData.thresholdPercentage = "0"; + } else { + await BiometricsApi().removeBioException( + "operatorBiometrics", "Iris", "rightEye"); + biometricAttributeData.isScanned = false; + biometricAttributeData.attemptNo = 0; + biometricAttributeData.listofImages = [ + "assets/svg/Left Eye.svg", + "assets/svg/Right Eye.svg" + ]; + biometricAttributeData.listOfBiometricsDto = []; + biometricAttributeData.qualityPercentage = 0.0; + biometricAttributeData.thresholdPercentage = "0"; + } + biometricAttributeData.exceptions[1] = + !(biometricAttributeData.exceptions[1]); + + if (biometricAttributeData.exceptions + .contains(true)) { + if (biometricAttributeData.exceptionType.isEmpty) { + biometricAttributeData.exceptionType = + "Permanent"; + } + } + if (!biometricAttributeData.exceptions + .contains(true)) { + biometricAttributeData.exceptionType = ""; + } + setState(() {}); + }, + child: SvgPicture.asset( + "assets/svg/right_iris.svg", + fit: BoxFit.fitHeight, + color: (biometricAttributeData.exceptions[1] == true) + ? secondaryColors.elementAt(25) + : Colors.transparent, + ), + )), + ), + ], + ), + ]), + ), + ); + } + if (biometricAttributeData.title == "Right Hand") { + return Stack( + children: [ + SizedBox( + height: 300, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Stack( + children: [ + SizedBox( + width: 300, + height: 300, + child: SvgPicture.asset( + "assets/svg/Right Hand.svg", + fit: BoxFit.fitHeight, + ), + ), + Positioned( + top: 95, + left: 67, + child: SvgPicture.asset( + "assets/svg/RH_1.svg", + height: 165, + color: (biometricAttributeData.exceptions[0] == true) + ? secondaryColors.elementAt(25) + : Colors.transparent, + )), + Positioned( + top: 55, + left: 117, + child: SvgPicture.asset( + "assets/svg/RH_2.svg", + height: 205, + color: (biometricAttributeData.exceptions[1] == true) + ? secondaryColors.elementAt(25) + : Colors.transparent, + )), + Positioned( + top: 97, + right: 97, + child: SvgPicture.asset( + "assets/svg/RH_3.svg", + height: 165, + color: (biometricAttributeData.exceptions[2] == true) + ? secondaryColors.elementAt(25) + : const Color.fromARGB(0, 221, 210, 210), + )), + Positioned( + top: 167, + right: 54, + child: SvgPicture.asset( + "assets/svg/RH_4.svg", + height: 100, + color: (biometricAttributeData.exceptions[3] == true) + ? secondaryColors.elementAt(25) + : Colors.transparent, + )), + ], + ), + ], + ), + ), + Positioned( + bottom: 20, + right: 20, + child: InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) => StatefulBuilder( + builder: (context, StateSetter setStateAlert) => + SingleChildScrollView( + child: Center( + child: AlertDialog( + insetPadding: EdgeInsets.symmetric( + vertical: (isMobileSize) ? 10 : 24, + horizontal: (isMobileSize) ? 10 : 40), + content: Container( + height: (isMobileSize) ? 500 : 720, + width: (isMobileSize) ? 404 : 760, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12)), + child: Column( + children: [ + Row( + children: [ + const SizedBox( + width: 50, + ), + const Spacer(), + Text( + "${biometricAttributeData.viewTitle} ${AppLocalizations.of(context)!.scan}", + style: TextStyle( + fontSize: + (isMobileSize) ? 20.h : 28.h, + fontWeight: bold, + color: blackShade1, + overflow: TextOverflow.ellipsis), + ), + const Spacer(), + IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: Icon( + Icons.close, + color: blackShade1, + weight: 25, + size: 28, + )), + ], + ), + Divider( + height: 30, + thickness: 1, + color: secondaryColors.elementAt(22), + ), + Stack( + children: [ + SizedBox( + height: (isMobileSize) ? 339 : 639, + width: (isMobileSize) ? 339 : 639, + child: SvgPicture.asset( + "assets/svg/Right Hand.svg", + fit: BoxFit.fitHeight, + ), + ), + Positioned( + top: (isMobileSize) ? 109 : 205, + left: (isMobileSize) ? 72 : 140, + child: InkWell( + onTap: () async { + if (!(biometricAttributeData + .exceptions + .elementAt(0)) == + true) { + await BiometricsApi() + .addBioException( + "operatorBiometrics", + "RightHand", + "rightIndex"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Right Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = + "0"; + } else { + await BiometricsApi() + .removeBioException( + "operatorBiometrics", + "RightHand", + "rightIndex"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Right Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = + "0"; + } + biometricAttributeData + .exceptions[0] = + !(biometricAttributeData + .exceptions[0]); + + if (biometricAttributeData + .exceptions + .contains(true)) { + if (biometricAttributeData + .exceptionType.isEmpty) { + biometricAttributeData + .exceptionType = + "Permanent"; + } + } + if (!biometricAttributeData + .exceptions + .contains(true)) { + biometricAttributeData + .exceptionType = ""; + } + setState(() {}); + setStateAlert(() {}); + }, + child: SvgPicture.asset( + "assets/svg/RH_1.svg", + height: + (isMobileSize) ? 204 : 385, + color: (biometricAttributeData + .exceptions[0] == + true) + ? secondaryColors + .elementAt(25) + : Colors.transparent, + ), + )), + Positioned( + top: (isMobileSize) ? 66 : 125, + left: (isMobileSize) ? 127 : 245, + child: InkWell( + onTap: () async { + if (!(biometricAttributeData + .exceptions + .elementAt(1)) == + true) { + await BiometricsApi() + .addBioException( + "operatorBiometrics", + "RightHand", + "rightMiddle"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Right Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = + "0"; + } else { + await BiometricsApi() + .removeBioException( + "operatorBiometrics", + "RightHand", + "rightMiddle"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Right Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = + "0"; + } + biometricAttributeData + .exceptions[1] = + !(biometricAttributeData + .exceptions[1]); + + if (biometricAttributeData + .exceptions + .contains(true)) { + if (biometricAttributeData + .exceptionType.isEmpty) { + biometricAttributeData + .exceptionType = + "Permanent"; + } + } + if (!biometricAttributeData + .exceptions + .contains(true)) { + biometricAttributeData + .exceptionType = ""; + } + setState(() {}); + setStateAlert(() {}); + }, + child: SvgPicture.asset( + "assets/svg/RH_2.svg", + height: + (isMobileSize) ? 247 : 465, + color: (biometricAttributeData + .exceptions[1] == + true) + ? secondaryColors + .elementAt(25) + : Colors.transparent, + ), + )), + Positioned( + top: (isMobileSize) ? 114 : 215, + right: (isMobileSize) ? 104 : 203, + child: InkWell( + onTap: () async { + if (!(biometricAttributeData + .exceptions + .elementAt(2)) == + true) { + await BiometricsApi() + .addBioException( + "operatorBiometrics", + "RightHand", + "rightRing"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Right Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = + "0"; + } else { + await BiometricsApi() + .removeBioException( + "operatorBiometrics", + "RightHand", + "rightRing"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Right Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = + "0"; + } + biometricAttributeData + .exceptions[2] = + !(biometricAttributeData + .exceptions[2]); + + if (biometricAttributeData + .exceptions + .contains(true)) { + if (biometricAttributeData + .exceptionType.isEmpty) { + biometricAttributeData + .exceptionType = + "Permanent"; + } + } + if (!biometricAttributeData + .exceptions + .contains(true)) { + biometricAttributeData + .exceptionType = ""; + } + setState(() {}); + setStateAlert(() {}); + }, + child: SvgPicture.asset( + "assets/svg/RH_3.svg", + height: + (isMobileSize) ? 204 : 385, + color: (biometricAttributeData + .exceptions[2] == + true) + ? secondaryColors + .elementAt(25) + : Colors.transparent, + ), + )), + Positioned( + top: (isMobileSize) ? 189 : 357, + right: (isMobileSize) ? 56 : 110, + child: InkWell( + onTap: () async { + if (!(biometricAttributeData + .exceptions + .elementAt(3)) == + true) { + await BiometricsApi() + .addBioException( + "operatorBiometrics", + "RightHand", + "rightLittle"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Right Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = + "0"; + } else { + await BiometricsApi() + .removeBioException( + "operatorBiometrics", + "RightHand", + "rightLittle"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Right Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = + "0"; + } + biometricAttributeData + .exceptions[3] = + !(biometricAttributeData + .exceptions[3]); + + if (biometricAttributeData + .exceptions + .contains(true)) { + if (biometricAttributeData + .exceptionType.isEmpty) { + biometricAttributeData + .exceptionType = + "Permanent"; + } + } + if (!biometricAttributeData + .exceptions + .contains(true)) { + biometricAttributeData + .exceptionType = ""; + } + setState(() {}); + setStateAlert(() {}); + }, + child: SvgPicture.asset( + "assets/svg/RH_4.svg", + height: + (isMobileSize) ? 132 : 250, + color: (biometricAttributeData + .exceptions[3] == + true) + ? secondaryColors + .elementAt(25) + : Colors.transparent, + ), + )), + ], + ), + ], + ), + ), + ), + ), + ), + ), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(1000), + color: solidPrimary), + height: 75, + width: 75, + child: Icon( + Icons.zoom_in, + color: pureWhite, + size: 35, + )))), + ], + ); + } + if (biometricAttributeData.title == "Left Hand") { + return Stack( + children: [ + SizedBox( + height: 300, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Stack( + children: [ + SizedBox( + width: 300, + height: 300, + child: SvgPicture.asset( + "assets/svg/Left Hand.svg", + fit: BoxFit.fitHeight, + ), + ), + Positioned( + top: 167, + left: 54, + child: SvgPicture.asset( + "assets/svg/LH_1.svg", + height: 100, + color: (biometricAttributeData.exceptions[3] == true) + ? secondaryColors.elementAt(25) + : Colors.transparent, + )), + Positioned( + top: 97, + left: 97, + child: SvgPicture.asset( + "assets/svg/LH_2.svg", + height: 165, + color: (biometricAttributeData.exceptions[2] == true) + ? secondaryColors.elementAt(25) + : Colors.transparent, + )), + Positioned( + top: 55, + right: 117, + child: SvgPicture.asset( + "assets/svg/LH_3.svg", + height: 205, + color: (biometricAttributeData.exceptions[1] == true) + ? secondaryColors.elementAt(25) + : Colors.transparent, + )), + Positioned( + top: 95, + right: 67, + child: SvgPicture.asset( + "assets/svg/LH_4.svg", + height: 165, + color: (biometricAttributeData.exceptions[0] == true) + ? secondaryColors.elementAt(25) + : Colors.transparent, + )), + ], + ), + ], + ), + ), + Positioned( + bottom: 20, + right: 20, + child: InkWell( + onTap: () { + showDialog( + context: context, + builder: (context) => StatefulBuilder( + builder: (context, setStateAlert) => + SingleChildScrollView( + child: AlertDialog( + content: Container( + height: (isMobileSize) ? 500 : 720, + width: (isMobileSize) ? 404 : 760, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12)), + child: Column( + children: [ + Row( + children: [ + const SizedBox( + width: 50, + ), + const Spacer(), + Text( + "${biometricAttributeData.viewTitle} ${AppLocalizations.of(context)!.scan}", + style: TextStyle( + fontSize: + (isMobileSize) ? 20.h : 28.h, + fontWeight: bold, + color: blackShade1, + overflow: TextOverflow.ellipsis), + ), + const Spacer(), + IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: Icon( + Icons.close, + color: blackShade1, + weight: 25, + size: 28, + )), + ], + ), + Divider( + height: 30, + thickness: 1, + color: secondaryColors.elementAt(22), + ), + Stack( + children: [ + SizedBox( + height: (isMobileSize) ? 339 : 639, + width: (isMobileSize) ? 339 : 639, + child: SvgPicture.asset( + "assets/svg/Left Hand.svg", + fit: BoxFit.fitHeight, + ), + ), + Positioned( + top: (isMobileSize) ? 189 : 357, + left: (isMobileSize) ? 52 : 110, + child: InkWell( + onTap: () async { + if (!(biometricAttributeData + .exceptions + .elementAt(3)) == + true) { + await BiometricsApi() + .addBioException( + "operatorBiometrics", + "LeftHand", + "leftLittle"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Left Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = "0"; + } else { + await BiometricsApi() + .removeBioException( + "operatorBiometrics", + "LeftHand", + "leftLittle"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Left Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = "0"; + } + biometricAttributeData + .exceptions[3] = + !(biometricAttributeData + .exceptions[3]); + + if (biometricAttributeData + .exceptions + .contains(true)) { + if (biometricAttributeData + .exceptionType.isEmpty) { + biometricAttributeData + .exceptionType = + "Permanent"; + } + } + if (!biometricAttributeData + .exceptions + .contains(true)) { + biometricAttributeData + .exceptionType = ""; + } + setState(() {}); + setStateAlert(() {}); + }, + child: SvgPicture.asset( + "assets/svg/LH_1.svg", + height: (isMobileSize) + ? 132.h + : 250.h, + color: (biometricAttributeData + .exceptions[3] == + true) + ? secondaryColors + .elementAt(25) + : Colors.transparent, + ), + )), + Positioned( + top: (isMobileSize) ? 114 : 215, + left: (isMobileSize) ? 110 : 203, + child: InkWell( + onTap: () async { + if (!(biometricAttributeData + .exceptions + .elementAt(2)) == + true) { + await BiometricsApi() + .addBioException( + "operatorBiometrics", + "LeftHand", + "leftRing"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Left Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = "0"; + } else { + await BiometricsApi() + .removeBioException( + "operatorBiometrics", + "LeftHand", + "leftRing"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Left Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = "0"; + } + biometricAttributeData + .exceptions[2] = + !(biometricAttributeData + .exceptions[2]); + + if (biometricAttributeData + .exceptions + .contains(true)) { + if (biometricAttributeData + .exceptionType.isEmpty) { + biometricAttributeData + .exceptionType = + "Permanent"; + } + } + if (!biometricAttributeData + .exceptions + .contains(true)) { + biometricAttributeData + .exceptionType = ""; + } + setState(() {}); + setStateAlert(() {}); + }, + child: SvgPicture.asset( + "assets/svg/LH_2.svg", + height: + (isMobileSize) ? 204 : 385, + color: (biometricAttributeData + .exceptions[2] == + true) + ? secondaryColors + .elementAt(25) + : Colors.transparent, + ), + )), + Positioned( + top: (isMobileSize) ? 66 : 125, + right: (isMobileSize) ? 130 : 245, + child: InkWell( + onTap: () async { + if (!(biometricAttributeData + .exceptions + .elementAt(1)) == + true) { + await BiometricsApi() + .addBioException( + "operatorBiometrics", + "LeftHand", + "leftMiddle"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Left Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = "0"; + } else { + await BiometricsApi() + .removeBioException( + "operatorBiometrics", + "LeftHand", + "leftMiddle"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Left Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = "0"; + } + biometricAttributeData + .exceptions[1] = + !(biometricAttributeData + .exceptions[1]); + + if (biometricAttributeData + .exceptions + .contains(true)) { + if (biometricAttributeData + .exceptionType.isEmpty) { + biometricAttributeData + .exceptionType = + "Permanent"; + } + } + if (!biometricAttributeData + .exceptions + .contains(true)) { + biometricAttributeData + .exceptionType = ""; + } + setState(() {}); + setStateAlert(() {}); + }, + child: SvgPicture.asset( + "assets/svg/LH_3.svg", + height: + (isMobileSize) ? 247 : 465, + color: (biometricAttributeData + .exceptions[1] == + true) + ? secondaryColors + .elementAt(25) + : Colors.transparent, + ), + )), + Positioned( + top: (isMobileSize) ? 109 : 205, + right: (isMobileSize) ? 73 : 140, + child: InkWell( + onTap: () async { + if (!(biometricAttributeData + .exceptions + .elementAt(0)) == + true) { + await BiometricsApi() + .addBioException( + "operatorBiometrics", + "LeftHand", + "leftIndex"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Left Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = "0"; + } else { + await BiometricsApi() + .removeBioException( + "operatorBiometrics", + "LeftHand", + "leftIndex"); + biometricAttributeData + .isScanned = false; + biometricAttributeData + .attemptNo = 0; + biometricAttributeData + .listofImages = [ + "assets/svg/Left Hand.svg" + ]; + biometricAttributeData + .listOfBiometricsDto = []; + biometricAttributeData + .qualityPercentage = 0; + biometricAttributeData + .thresholdPercentage = "0"; + } + biometricAttributeData + .exceptions[0] = + !(biometricAttributeData + .exceptions[0]); + + if (biometricAttributeData + .exceptions + .contains(true)) { + if (biometricAttributeData + .exceptionType.isEmpty) { + biometricAttributeData + .exceptionType = + "Permanent"; + } + } + if (!biometricAttributeData + .exceptions + .contains(true)) { + biometricAttributeData + .exceptionType = ""; + } + setState(() {}); + setStateAlert(() {}); + }, + child: SvgPicture.asset( + "assets/svg/LH_4.svg", + height: + (isMobileSize) ? 204 : 385, + color: (biometricAttributeData + .exceptions[0] == + true) + ? secondaryColors + .elementAt(25) + : Colors.transparent, + ), + )), + ], + ), + ], + ), + ), + ), + ), + ), + ); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(1000), + color: solidPrimary), + height: 75, + width: 75, + child: Icon( + Icons.zoom_in, + color: pureWhite, + size: 35, + )))), + ], + ); + } + if (biometricAttributeData.title == "Thumbs") { + return SizedBox( + height: 300, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Stack( + children: [ + SizedBox( + height: 300, + width: 300, + child: SvgPicture.asset( + "assets/svg/Thumbs.svg", + fit: BoxFit.fitHeight, + ), + ), + Positioned( + top: 49, + left: 5, + child: InkWell( + onTap: () async { + if (!(biometricAttributeData.exceptions.elementAt(0)) == + true) { + await BiometricsApi().addBioException( + "operatorBiometrics", "Thumbs", "leftThumb"); + biometricAttributeData.isScanned = false; + biometricAttributeData.attemptNo = 0; + biometricAttributeData.listofImages = [ + "assets/svg/Thumbs.svg" + ]; + biometricAttributeData.listOfBiometricsDto = []; + biometricAttributeData.qualityPercentage = 0; + biometricAttributeData.thresholdPercentage = "0"; + } else { + await BiometricsApi().removeBioException( + "operatorBiometrics", "Thumbs", "leftThumb"); + biometricAttributeData.isScanned = false; + biometricAttributeData.attemptNo = 0; + biometricAttributeData.listofImages = [ + "assets/svg/Thumbs.svg" + ]; + biometricAttributeData.listOfBiometricsDto = []; + biometricAttributeData.qualityPercentage = 0; + biometricAttributeData.thresholdPercentage = "0"; + } + biometricAttributeData.exceptions[0] = + !(biometricAttributeData.exceptions[0]); + + if (biometricAttributeData.exceptions.contains(true)) { + if (biometricAttributeData.exceptionType.isEmpty) { + biometricAttributeData.exceptionType = "Permanent"; + } + } + if (!biometricAttributeData.exceptions.contains(true)) { + biometricAttributeData.exceptionType = ""; + } + setState(() {}); + }, + child: SvgPicture.asset( + "assets/svg/L_Thumb.svg", + color: (biometricAttributeData.exceptions[0] == true) + ? secondaryColors.elementAt(25) + : Colors.transparent, + ), + ), + ), + Positioned( + top: 49, + right: 5, + child: InkWell( + onTap: () async { + if (!(biometricAttributeData.exceptions.elementAt(1)) == + true) { + await BiometricsApi().addBioException( + "operatorBiometrics", "Thumbs", "rightThumb"); + biometricAttributeData.isScanned = false; + biometricAttributeData.attemptNo = 0; + biometricAttributeData.listofImages = [ + "assets/svg/Thumbs.svg" + ]; + biometricAttributeData.listOfBiometricsDto = []; + biometricAttributeData.qualityPercentage = 0; + biometricAttributeData.thresholdPercentage = "0"; + } else { + await BiometricsApi().removeBioException( + "operatorBiometrics", "Thumbs", "rightThumb"); + biometricAttributeData.isScanned = false; + biometricAttributeData.attemptNo = 0; + biometricAttributeData.listofImages = [ + "assets/svg/Thumbs.svg" + ]; + biometricAttributeData.listOfBiometricsDto = []; + biometricAttributeData.qualityPercentage = 0; + biometricAttributeData.thresholdPercentage = "0"; + } + biometricAttributeData.exceptions[1] = + !(biometricAttributeData.exceptions[1]); + + if (biometricAttributeData.exceptions.contains(true)) { + if (biometricAttributeData.exceptionType.isEmpty) { + biometricAttributeData.exceptionType = "Permanent"; + } + } + if (!biometricAttributeData.exceptions.contains(true)) { + biometricAttributeData.exceptionType = ""; + } + setState(() {}); + }, + child: SvgPicture.asset( + "assets/svg/R_Thumb.svg", + color: (biometricAttributeData.exceptions[1] == true) + ? secondaryColors.elementAt(25) + : Colors.transparent, + ), + )), + ], + ), + ], + ), + ); + } + if (biometricAttributeData.title == "Face") { + return SizedBox( + height: 300, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + height: 300, + width: 300, + child: SvgPicture.asset( + "assets/svg/Face.svg", + fit: BoxFit.fitHeight, + ), + ), + ], + )); + } + // if (biometricAttributeData.title == "Exception") { + // return SizedBox( + // height: 300, + // child: Row( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // SizedBox( + // height: 300, + // width: 380, + // child: SvgPicture.asset( + // "assets/svg/Exception.svg", + // fit: BoxFit.fitHeight, + // )), + // ], + // )); + // } + + return Container(); + } + + Widget _exceptionBlock() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: Container( + decoration: BoxDecoration( + color: pureWhite, + border: + Border.all(color: secondaryColors.elementAt(14), width: 1), + ), + height: 353, + width: (isPortrait) ? double.infinity : 760.w, + child: _returnExceptionImage(), + ), + ), + const SizedBox( + height: 40, + ), + (biometricAttributeData.title != "Face" && + biometricAttributeData.title != "Exception") + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 40, + ), + Text( + AppLocalizations.of(context)!.exception_type, + style: TextStyle( + fontSize: 25, fontWeight: semiBold, color: blackShade1), + ), + const SizedBox( + height: 18, + ), + Row( + children: [ + Expanded( + child: OutlinedButton( + onPressed: () { + if (biometricAttributeData.exceptions + .contains(true)) { + biometricAttributeData.exceptionType = + "Permanent"; + } + setState(() {}); + }, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + (biometricAttributeData.exceptionType == + "Permanent") + ? secondaryColors.elementAt(12) + : pureWhite), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(36), + ), + ), + side: MaterialStateProperty.all( + BorderSide( + color: secondaryColors.elementAt(12))), + padding: + MaterialStateProperty.all( + EdgeInsets.symmetric( + horizontal: (isMobileSize) ? 10.w : 109.w, + vertical: (isMobileSize) ? 10.h : 20.h), + ), + ), + child: Text( + AppLocalizations.of(context)!.permanent, + style: TextStyle( + fontSize: (isMobileSize) ? 16.h : 24.h, + fontWeight: FontWeight.w400, + color: (biometricAttributeData.exceptionType == + "Permanent") + ? pureWhite + : blackShade1), + ), + ), + ), + const SizedBox( + width: 30, + ), + Expanded( + child: OutlinedButton( + onPressed: () { + if (biometricAttributeData.exceptions + .contains(true)) { + biometricAttributeData.exceptionType = + "Temporary"; + } + setState(() {}); + }, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + (biometricAttributeData.exceptionType == + "Temporary") + ? secondaryColors.elementAt(12) + : pureWhite), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(36), + ), + ), + side: MaterialStateProperty.all( + BorderSide( + color: secondaryColors.elementAt(12))), + padding: + MaterialStateProperty.all( + EdgeInsets.symmetric( + horizontal: (isMobileSize) ? 10.w : 109.w, + vertical: (isMobileSize) ? 10.h : 20.h), + ), + ), + child: Text( + AppLocalizations.of(context)!.temporary, + style: TextStyle( + fontSize: (isMobileSize) ? 16.h : 24.h, + fontWeight: FontWeight.w400, + color: (biometricAttributeData.exceptionType == + "Temporary") + ? pureWhite + : blackShade1), + ), + ), + ), + ], + ), + const SizedBox( + height: 40, + ), + Text( + AppLocalizations.of(context)!.comments, + style: TextStyle( + fontSize: 25, fontWeight: semiBold, color: blackShade1), + ), + const SizedBox( + height: 20, + ), + TextField( + maxLines: 10, + decoration: InputDecoration( + fillColor: pureWhite, + hintText: AppLocalizations.of(context)! + .add_comments_for_marking_the_exception, + hintStyle: TextStyle( + fontSize: 28, + fontWeight: regular, + color: secondaryColors.elementAt(1)), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(6), + borderSide: BorderSide( + color: secondaryColors.elementAt(12), + ), + ), + ), + ), + ], + ) + : Container( + height: 96, + decoration: BoxDecoration( + color: secondaryColors.elementAt(23), + borderRadius: BorderRadius.circular(6)), + child: Center( + child: Text( + "${AppLocalizations.of(context)!.marking_exceptions_on} ${biometricAttributeData.viewTitle} ${AppLocalizations.of(context)!.is_not_allowed}", + style: TextStyle( + fontSize: 25, + fontWeight: semiBold, + color: secondaryColors.elementAt(24)), + ), + ), + ), + SizedBox( + height: 20.h, + ), + ], + ); + } + + late BiometricAttributeData biometricAttributeData; + late BiometricCaptureControlProvider biometricCaptureControlProvider; + + @override + Widget build(BuildContext context) { + isPortrait = MediaQuery.of(context).orientation == Orientation.portrait; + setInitialState(); + biometricCaptureControlProvider = + Provider.of(context, listen: false); + return SafeArea( + child: Scaffold( + bottomNavigationBar: Container( + color: pureWhite, + padding: EdgeInsets.symmetric( + horizontal: (isMobileSize) ? 30.w : 80.w, + vertical: 16.h, + ), + height: (isMobileSize) ? 60.w : 100.h, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + const Spacer(), + ElevatedButton( + style: ButtonStyle( + maximumSize: + MaterialStateProperty.all(const Size(215, 68)), + minimumSize: + MaterialStateProperty.all(const Size(215, 68)), + ), + onPressed: () { + List bioAttributes = [ + "Iris", + "Right Hand", + "Left Hand", + "Thumbs", + "Face" + ]; + var nextElement = _getNextElement( + bioAttributes, + context + .read() + .biometricAttribute); + if (nextElement != null) { + setState(() { + context + .read() + .biometricAttribute = nextElement; + }); + } else { + Navigator.pop(context); + } + }, + child: Text(AppLocalizations.of(context)!.next_button, + style: TextStyle(fontSize: 24, fontWeight: bold)), + ), + ], + ), + ), + appBar: PreferredSize( + preferredSize: Size.fromHeight((isMobileSize) ? 60 : 70), + child: AppBar( + automaticallyImplyLeading: false, + flexibleSpace: SizedBox( + height: (isMobileSize) ? 60 : 70, + child: Card( + margin: const EdgeInsets.all(0), + child: Padding( + padding: (isMobileSize) + ? const EdgeInsets.fromLTRB(20, 9, 0, 9) + : const EdgeInsets.fromLTRB(20, 18, 0, 18), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Supervisor's Biometric Verification", + style: Theme.of(context).textTheme.titleLarge?.copyWith( + fontSize: (isMobileSize) ? 14.h : 24.h, + color: blackShade1, + fontWeight: semiBold, + overflow: TextOverflow.ellipsis), + ), + Padding( + padding: const EdgeInsets.only(right: 30), + child: InkWell( + onTap: () { + Navigator.pop(context); + }, + child: Image.asset( + "assets/images/Group 57951.png", + height: (isMobileSize) ? 30.h : 52.h, + ), + ), + ) + ], + ), + ), + ), + ), + ), + ), + body: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.fromLTRB(20, 40, 20, 0), + child: Column( + children: [ + const SizedBox( + width: double.infinity, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + child: InkWell( + onTap: () { + setState(() { + context + .read() + .biometricCaptureScanBlockTabIndex = 1; + }); + }, + child: Container( + decoration: BoxDecoration( + color: (context + .read() + .biometricCaptureScanBlockTabIndex == + 1) + ? solidPrimary + : pureWhite, + border: (context + .read() + .biometricCaptureScanBlockTabIndex == + 1) + ? const Border() + : Border( + bottom: BorderSide( + color: solidPrimary, width: 3), + ), + ), + height: 84, + child: Center( + child: Text( + "${biometricAttributeData.viewTitle} ${AppLocalizations.of(context)!.scan}", + style: TextStyle( + fontSize: (isMobileSize) ? 18 : 24, + fontWeight: semiBold, + color: (context + .read< + BiometricCaptureControlProvider>() + .biometricCaptureScanBlockTabIndex == + 1) + ? pureWhite + : blackShade1), + ), + ), + ), + ), + ), + Expanded( + child: InkWell( + onTap: () { + setState(() { + context + .read() + .biometricCaptureScanBlockTabIndex = 2; + }); + }, + child: Container( + decoration: BoxDecoration( + color: (context + .read() + .biometricCaptureScanBlockTabIndex == + 2) + ? solidPrimary + : pureWhite, + border: (context + .read() + .biometricCaptureScanBlockTabIndex == + 2) + ? const Border() + : Border( + bottom: BorderSide( + color: solidPrimary, width: 3), + ), + ), + height: 84, + child: Center( + child: Text( + AppLocalizations.of(context)!.mark_exception, + style: TextStyle( + fontSize: (isMobileSize) ? 18 : 24, + fontWeight: semiBold, + color: (context + .read< + BiometricCaptureControlProvider>() + .biometricCaptureScanBlockTabIndex == + 2) + ? pureWhite + : blackShade1), + ), + ), + ), + ), + ) + ], + ), + const SizedBox( + height: 40, + ), + (context + .read() + .biometricCaptureScanBlockTabIndex == + 1) + ? _scanBlock() + : _exceptionBlock() + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/ui/onboard/widgets/operator_biometrics_capture_view.dart b/lib/ui/onboard/widgets/operator_biometrics_capture_view.dart new file mode 100644 index 000000000..950997fe2 --- /dev/null +++ b/lib/ui/onboard/widgets/operator_biometrics_capture_view.dart @@ -0,0 +1,415 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; +import 'package:registration_client/model/biometric_attribute_data.dart'; +import 'package:registration_client/pigeon/biometrics_pigeon.dart'; +import 'package:registration_client/provider/biometric_capture_control_provider.dart'; +import 'package:registration_client/provider/global_provider.dart'; +import 'package:registration_client/ui/onboard/widgets/operator_biometric_capture_scan_block_view.dart'; +import 'package:registration_client/utils/app_config.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:responsive_grid_list/responsive_grid_list.dart'; + +class OperatorBiometricsCaptureView extends StatefulWidget { + const OperatorBiometricsCaptureView({super.key}); + + @override + State createState() => + _OperatorBiometricsCaptureState(); +} + +class _OperatorBiometricsCaptureState + extends State { + bool isSavingBiometrics = false; + Widget _getBiometricCaptureSelectionBlockMobile( + BiometricAttributeData biometricAttributeData) { + return InkWell( + onTap: () { + setState(() { + context.read().biometricAttribute = + biometricAttributeData.title; + }); + + final providerCopy = Provider.of( + context, + listen: false); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ChangeNotifierProvider.value( + value: providerCopy, + child: OperatorBiometricCaptureScanBlockView(), + ))).then((value) { + setState(() {}); + }); + }, + child: Center( + child: Stack( + children: [ + Container( + height: 335.h, + width: 372.h, + decoration: BoxDecoration( + color: pureWhite, + border: Border.all( + color: (biometricAttributeData.isScanned == true) + ? (biometricAttributeData.exceptions.contains(true)) + ? secondaryColors.elementAt(16) + : secondaryColors.elementAt(11) + : (context + .watch< + BiometricCaptureControlProvider>() + .biometricAttribute == + biometricAttributeData.title) + ? secondaryColors.elementAt(12) + : secondaryColors.elementAt(14)), + borderRadius: BorderRadius.circular(10)), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: SvgPicture.asset( + "assets/svg/${biometricAttributeData.title}.svg", + height: 200.h, + width: 200.h, + ), + ), + SizedBox( + height: 10.h, + ), + Text( + "${biometricAttributeData.viewTitle} ${AppLocalizations.of(context)!.scan}", + style: TextStyle( + fontSize: 28, + fontWeight: semiBold, + color: blackShade1, + ), + ) + ], + ), + ), + if (biometricAttributeData.isScanned == true) + Positioned( + top: 15, + right: 15, + child: (biometricAttributeData.exceptions.contains(true)) + ? Image.asset( + "assets/images/Group 57548@2x.png", + ) + : Image.asset( + "assets/images/Group 57745@2x.png", + )), + if (biometricAttributeData.isScanned == true) + Positioned( + top: 20, + left: 20, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 10, vertical: 7), + decoration: BoxDecoration( + color: (biometricAttributeData.qualityPercentage + .toInt() < + int.parse(biometricAttributeData + .thresholdPercentage)) + ? secondaryColors.elementAt(26) + : secondaryColors.elementAt(11), + borderRadius: BorderRadius.circular(50)), + height: 40, + child: Text( + "${biometricAttributeData.qualityPercentage.toInt()}%", + style: TextStyle( + fontSize: 20, + color: pureWhite, + fontWeight: semiBold)), + )), + ], + ), + )); + } + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Scaffold( + backgroundColor: secondaryColors.elementAt(10), + bottomNavigationBar: Container( + height: 100.h, + color: pureWhite, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), + child: ElevatedButton( + onPressed: () async { + if (context + .read() + .iris + .isScanned && + context + .read() + .rightHand + .isScanned && + context + .read() + .leftHand + .isScanned && + context + .read() + .thumbs + .isScanned && + context + .read() + .face + .isScanned) { + setState(() { + isSavingBiometrics = true; + }); + + String isOperatorBiometricSaved = ""; + await BiometricsApi().saveOperatorBiometrics().timeout( + Duration(seconds: 5), + onTimeout: () { + setState(() { + isSavingBiometrics = false; + }); + return ""; + }, + ).then((value) { + isOperatorBiometricSaved = value; + }); + + setState(() { + isSavingBiometrics = false; + }); + if (isOperatorBiometricSaved != "") { + Navigator.pop(context); + showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + content: Container( + height: 474.h, + width: 574.w, + child: Column( + children: [ + SizedBox( + height: 70.h, + width: double.infinity, + ), + SvgPicture.asset( + "assets/svg/success_message_icon.svg"), + Text( + "You have onboarded successfully.", + style: TextStyle( + fontSize: 28, + fontWeight: semiBold, + color: Color(0xFF000000)), + ), + SizedBox( + height: 62.h, + ), + ElevatedButton( + onPressed: () { + Navigator.pop(context); + }, + child: Text( + "HOME", + style: TextStyle( + fontSize: 19, + fontWeight: bold, + color: pureWhite), + ), + style: ButtonStyle( + fixedSize: MaterialStateProperty.all( + Size(564, 70))), + ) + ], + ), + ), + ), + ); + + setState(() { + context.read().setCurrentIndex(1); + }); + } + } + }, + child: isSavingBiometrics + ? CircularProgressIndicator( + color: appWhite, + ) + : Text( + "VERIFY & SAVE", + style: Theme.of(context) + .textTheme + .bodyLarge + ?.copyWith(fontSize: 26.h, color: pureWhite), + ), + style: OutlinedButton.styleFrom( + backgroundColor: (context + .read() + .iris + .isScanned && + context + .read() + .rightHand + .isScanned && + context + .read() + .leftHand + .isScanned && + context + .read() + .thumbs + .isScanned && + context + .read() + .face + .isScanned) + ? solidPrimary + : secondaryColors.elementAt(22)), + ), + ), + ), + appBar: PreferredSize( + preferredSize: Size.fromHeight(70.h), + child: AppBar( + backgroundColor: pureWhite, + automaticallyImplyLeading: false, + flexibleSpace: Card( + elevation: 0, + margin: const EdgeInsets.all(0), + child: Padding( + padding: (isMobileSize) + ? const EdgeInsets.fromLTRB(20, 9, 0, 9) + : const EdgeInsets.fromLTRB(20, 18, 0, 18), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Supervisor's Biometric Verification", + style: Theme.of(context).textTheme.titleLarge?.copyWith( + fontSize: (isMobileSize) ? 16.w : 24.w, + color: blackShade1, + fontWeight: semiBold, + overflow: TextOverflow.ellipsis), + ), + // SizedBox( + // height: (isMobileSize)?20.h:52.h, + // ), + ], + ), + ), + ), + ), + ), + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + width: double.infinity, + ), + + // SizedBox( + // width: double.infinity, + // child: + // ), + SizedBox( + height: 15.h, + ), + Column( + children: [ + Container( + margin: const EdgeInsets.fromLTRB(20, 0, 20, 20), + height: (isMobileSize) + ? ((((5.toDouble())).ceil() * 335.h) + 409.h) + : ((((5.toDouble()) / 2).ceil() * 335.h) + 70.h), + width: double.infinity, + child: ResponsiveGridList( + listViewBuilderOptions: ListViewBuilderOptions( + physics: const NeverScrollableScrollPhysics()), + minItemWidth: 372.h, + verticalGridSpacing: 17, + horizontalGridMargin: 30, + minItemsPerRow: (isMobileSize) ? 1 : 2, + maxItemsPerRow: (isMobileSize) ? 1 : 2, + children: [ + if (context + .read() + .operatorOnboardingAttributes + .contains("leftEye") && + context + .read() + .operatorOnboardingAttributes + .contains("rightEye")) + _getBiometricCaptureSelectionBlockMobile(context + .read() + .iris), + if (context + .read() + .operatorOnboardingAttributes + .contains("rightLittle") && + context + .read() + .operatorOnboardingAttributes + .contains("rightRing") && + context + .read() + .operatorOnboardingAttributes + .contains("rightMiddle") && + context + .read() + .operatorOnboardingAttributes + .contains("rightIndex")) + _getBiometricCaptureSelectionBlockMobile(context + .read() + .rightHand), + if (context + .read() + .operatorOnboardingAttributes + .contains("leftLittle") && + context + .read() + .operatorOnboardingAttributes + .contains("leftRing") && + context + .read() + .operatorOnboardingAttributes + .contains("leftMiddle") && + context + .read() + .operatorOnboardingAttributes + .contains("leftIndex")) + _getBiometricCaptureSelectionBlockMobile(context + .read() + .leftHand), + if (context + .read() + .operatorOnboardingAttributes + .contains("rightThumb") && + context + .read() + .operatorOnboardingAttributes + .contains("leftThumb")) + _getBiometricCaptureSelectionBlockMobile(context + .read() + .thumbs), + if (context + .read() + .operatorOnboardingAttributes + .contains("face")) + _getBiometricCaptureSelectionBlockMobile(context + .read() + .face), + ]), + ) + ], + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/ui/onboard/widgets/operator_onboarding_biometrics_capture_control.dart b/lib/ui/onboard/widgets/operator_onboarding_biometrics_capture_control.dart new file mode 100644 index 000000000..abdc6d503 --- /dev/null +++ b/lib/ui/onboard/widgets/operator_onboarding_biometrics_capture_control.dart @@ -0,0 +1,115 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; +import 'package:registration_client/model/biometric_attribute_data.dart'; +import 'package:registration_client/pigeon/biometrics_pigeon.dart'; +import 'package:registration_client/provider/biometric_capture_control_provider.dart'; +import 'package:registration_client/provider/global_provider.dart'; +import 'package:registration_client/provider/registration_task_provider.dart'; +import 'package:registration_client/ui/onboard/widgets/operator_biometrics_capture_view.dart'; +import 'package:registration_client/utils/app_config.dart'; +import 'package:registration_client/utils/stateful_wrapper.dart'; +import 'package:responsive_grid_list/responsive_grid_list.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +class OperatorOnboardingBiometricsCaptureControl extends StatelessWidget { + const OperatorOnboardingBiometricsCaptureControl({super.key}); + + @override + Widget build(BuildContext context) { + return ChangeNotifierProvider( + lazy: true, + create: (_) => BiometricCaptureControlProvider(), + builder: (context, child) => + OperatorOnboardingBiometricsCaptureControlInitialization()); + } +} + +class OperatorOnboardingBiometricsCaptureControlInitialization + extends StatelessWidget { + const OperatorOnboardingBiometricsCaptureControlInitialization({super.key}); + + @override + Widget build(BuildContext context) { + _getOperatorOnboardingAttributes() async { + await BiometricsApi() + .getMapValue("mosip.registration.operator.onboarding.bioattributes") + .then((value) { + context.read().operatorOnboardingAttributes = value; + }); + } + + setInitialBioAttribute() async { + context.read().biometricAttribute = + "Iris"; + + context.read().iris.viewTitle = + AppLocalizations.of(context)!.iris; + context.read().leftHand.viewTitle = + AppLocalizations.of(context)!.left_hand; + context.read().rightHand.viewTitle = + AppLocalizations.of(context)!.right_hand; + context.read().thumbs.viewTitle = + AppLocalizations.of(context)!.thumbs; + context.read().face.viewTitle = + AppLocalizations.of(context)!.face; + context.read().biometricAttribute = + "Iris"; + context.read().customSetterFace( + int.parse(await BiometricsApi() + .getMapValue("mosip.registration.num_of_face_retries")), + "noOfCapturesAllowed"); + context.read().customSetterThumbs( + int.parse(await BiometricsApi() + .getMapValue("mosip.registration.num_of_fingerprint_retries")), + "noOfCapturesAllowed"); + context.read().customSetterIris( + int.parse(await BiometricsApi() + .getMapValue("mosip.registration.num_of_iris_retries")), + "noOfCapturesAllowed"); + context.read().customSetterLeftHand( + int.parse(await BiometricsApi() + .getMapValue("mosip.registration.num_of_fingerprint_retries")), + "noOfCapturesAllowed"); + context.read().customSetterRightHand( + int.parse(await BiometricsApi() + .getMapValue("mosip.registration.num_of_fingerprint_retries")), + "noOfCapturesAllowed"); + await _getOperatorOnboardingAttributes(); + } + + context.read().customSetterIris( + context + .read() + .thresholdValuesMap["mosip.registration.iris_threshold"]!, + "thresholdPercentage"); + context.read().customSetterLeftHand( + context.read().thresholdValuesMap[ + "mosip.registration.leftslap_fingerprint_threshold"]!, + "thresholdPercentage"); + context.read().customSetterRightHand( + context.read().thresholdValuesMap[ + "mosip.registration.rightslap_fingerprint_threshold"]!, + "thresholdPercentage"); + context.read().customSetterThumbs( + context.read().thresholdValuesMap[ + "mosip.registration.thumbs_fingerprint_threshold"]!, + "thresholdPercentage"); + context.read().customSetterFace( + context + .read() + .thresholdValuesMap["mosip.registration.face_threshold"]!, + "thresholdPercentage"); + bool isPortrait = + MediaQuery.of(context).orientation == Orientation.portrait; + return StatefulWrapper( + onInit: () { + setInitialBioAttribute() + .then((value) => debugPrint("State Initialized")); + }, + child: (isPortrait) //Condition to rerender on changing of orientation + ? OperatorBiometricsCaptureView() + : OperatorBiometricsCaptureView()); + } +} diff --git a/lib/ui/process_ui/widgets/language_selector.dart b/lib/ui/process_ui/widgets/language_selector.dart index 9756d93a2..a637d04e5 100644 --- a/lib/ui/process_ui/widgets/language_selector.dart +++ b/lib/ui/process_ui/widgets/language_selector.dart @@ -58,6 +58,8 @@ class _LanguageSelectorState extends State { } _navigateToConsentPage() async { + context.read().fieldDisplayValues = {}; + await context.read().fieldValues(widget.newProcess); globalProvider.getThresholdValues(); globalProvider.fieldDisplayValues = {}; await globalProvider.fieldValues(widget.newProcess); diff --git a/lib/ui/process_ui/widgets_mobile/biometric_capture_control_portrait.dart b/lib/ui/process_ui/widgets_mobile/biometric_capture_control_portrait.dart index 881099e5e..0899fe39f 100644 --- a/lib/ui/process_ui/widgets_mobile/biometric_capture_control_portrait.dart +++ b/lib/ui/process_ui/widgets_mobile/biometric_capture_control_portrait.dart @@ -54,8 +54,6 @@ class _BiometricCaptureControlPortraitState BiometricAttributeData biometricAttributeData) { return InkWell( onTap: () { - context.read().biometricAttribute = - biometricAttributeData.title; context.read().biometricAttribute = biometricAttributeData.title; final providerCopy = Provider.of( diff --git a/lib/ui/process_ui/widgets_mobile/biometric_capture_scan_block_portrait.dart b/lib/ui/process_ui/widgets_mobile/biometric_capture_scan_block_portrait.dart index 3e92360c2..d07a11053 100644 --- a/lib/ui/process_ui/widgets_mobile/biometric_capture_scan_block_portrait.dart +++ b/lib/ui/process_ui/widgets_mobile/biometric_capture_scan_block_portrait.dart @@ -171,6 +171,16 @@ class _BiometricCaptureScanBlockPortraitState _showCustomAlert(currentAttemptNo, temp); } + noOfTrue(List list) { + int i = 0; + for (var e in list) { + if (e == true) { + i++; + } + } + return i; + } + generateList(String key, BiometricAttributeData data) { List list = []; @@ -318,97 +328,148 @@ class _BiometricCaptureScanBlockPortraitState SizedBox( height: 6.h, ), - Column( - crossAxisAlignment: CrossAxisAlignment.center, + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - Text( - AppLocalizations.of(context)!.attempts, - style: Theme.of(context).textTheme.bodyLarge?.copyWith( - fontSize: 24, color: blackShade1, fontWeight: semiBold), - ), - const SizedBox( - height: 29.4, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, + Column( + crossAxisAlignment: CrossAxisAlignment.center, children: [ - for (int i = 1; - i <= biometricAttributeData.noOfCapturesAllowed; - i++) - Padding( - padding: const EdgeInsets.only(right: 16.3), - child: InkWell( - onTap: () async { - if (biometricAttributeData.attemptNo >= i) { - await BiometricsApi() - .getBiometrics( - widget.field.id!, - biometricAttributeData.title - .replaceAll(" ", ""), - i) - .then((value) { - biometricAttributeData.listOfBiometricsDto - .clear(); - for (var e in value) { - biometricAttributeData.listOfBiometricsDto - .add(BiometricsDto.fromJson( - json.decode(e!))); - } - }); + Text( + AppLocalizations.of(context)!.attempts, + style: Theme.of(context).textTheme.bodyLarge?.copyWith( + fontSize: 24, + color: blackShade1, + fontWeight: semiBold), + ), + const SizedBox( + height: 29.4, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + for (int i = 1; + i <= biometricAttributeData.noOfCapturesAllowed; + i++) + Padding( + padding: const EdgeInsets.only(right: 16.3), + child: InkWell( + onTap: () async { + if (biometricAttributeData.attemptNo >= i) { + await BiometricsApi() + .getBiometrics( + widget.field.id!, + biometricAttributeData.title + .replaceAll(" ", ""), + i) + .then((value) { + biometricAttributeData.listOfBiometricsDto + .clear(); + for (var e in value) { + biometricAttributeData + .listOfBiometricsDto + .add(BiometricsDto.fromJson( + json.decode(e!))); + } + }); - setState(() { - biometricAttributeData.qualityPercentage = - context - .read< - BiometricCaptureControlProvider>() - .avgScore(biometricAttributeData - .listOfBiometricsDto); - }); - await BiometricsApi() - .extractImageValuesByAttempt( - widget.field.id!, - biometricAttributeData.title - .replaceAll(" ", ""), - i) - .then((value) { - biometricAttributeData.listofImages = value; - }); - setState(() {}); - } - }, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 7.3, - horizontal: 30, - ), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - border: Border.all( - color: secondaryColors.elementAt(17), - ), - color: (biometricAttributeData.attemptNo < i) - ? secondaryColors.elementAt(18) - : secondaryColors.elementAt(11), - ), - child: Text( - i.toString(), - style: Theme.of(context) - .textTheme - .bodyLarge - ?.copyWith( - fontSize: 21, - color: - (biometricAttributeData.attemptNo < + setState(() { + biometricAttributeData.qualityPercentage = + context + .read< + BiometricCaptureControlProvider>() + .avgScore(biometricAttributeData + .listOfBiometricsDto); + }); + await BiometricsApi() + .extractImageValuesByAttempt( + widget.field.id!, + biometricAttributeData.title + .replaceAll(" ", ""), + i) + .then((value) { + biometricAttributeData.listofImages = + value; + }); + setState(() {}); + } + }, + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 7.3, + horizontal: 30, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + border: Border.all( + color: secondaryColors.elementAt(17), + ), + color: + (biometricAttributeData.attemptNo < i) + ? secondaryColors.elementAt(18) + : secondaryColors.elementAt(11), + ), + child: Text( + i.toString(), + style: Theme.of(context) + .textTheme + .bodyLarge + ?.copyWith( + fontSize: 21, + color: (biometricAttributeData + .attemptNo < i) ? secondaryColors.elementAt(19) : pureWhite, - fontWeight: semiBold), + fontWeight: semiBold), + ), + ), ), ), + ], + ), + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + AppLocalizations.of(context)!.exceptions, + style: Theme.of(context).textTheme.bodyLarge?.copyWith( + fontSize: 24, + color: blackShade1, + fontWeight: semiBold), + ), + const SizedBox( + height: 29.4, + ), + Padding( + padding: const EdgeInsets.only(right: 16.3), + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 7.3, + horizontal: 30, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + border: Border.all( + color: secondaryColors.elementAt(17), + ), + color: secondaryColors.elementAt(18), + ), + child: Text( + noOfTrue(biometricAttributeData.exceptions).toString(), + style: Theme.of(context) + .textTheme + .bodyLarge + ?.copyWith( + fontSize: 21, + color: secondaryColors.elementAt(19), + fontWeight: semiBold), ), ), + ), ], - ) + ), ], ), SizedBox( @@ -619,24 +680,18 @@ class _BiometricCaptureScanBlockPortraitState .iris .exceptions .contains(true)) { - if(!context + if (!context .read() .exceptionAttributes .contains("Iris")) { - context - .read() - .exceptionAttributes - .add("Iris"); + context.read().exceptionAttributes.add("Iris"); } } else { if (context .read() .exceptionAttributes .contains("Iris")) { - context - .read() - .exceptionAttributes - .remove("Iris"); + context.read().exceptionAttributes.remove("Iris"); } } } @@ -650,10 +705,7 @@ class _BiometricCaptureScanBlockPortraitState .read() .exceptionAttributes .contains("Right Hand")) { - context - .read() - .exceptionAttributes - .add("Right Hand"); + context.read().exceptionAttributes.add("Right Hand"); } } else { if (context @@ -677,10 +729,7 @@ class _BiometricCaptureScanBlockPortraitState .read() .exceptionAttributes .contains("Left Hand")) { - context - .read() - .exceptionAttributes - .add("Left Hand"); + context.read().exceptionAttributes.add("Left Hand"); } } else { if (context @@ -704,20 +753,14 @@ class _BiometricCaptureScanBlockPortraitState .read() .exceptionAttributes .contains("Thumbs")) { - context - .read() - .exceptionAttributes - .add("Thumbs"); + context.read().exceptionAttributes.add("Thumbs"); } } else { if (context .read() .exceptionAttributes .contains("Thumbs")) { - context - .read() - .exceptionAttributes - .remove("Thumbs"); + context.read().exceptionAttributes.remove("Thumbs"); } } } @@ -1269,7 +1312,8 @@ class _BiometricCaptureScanBlockPortraitState .exceptionType = ""; } updateExceptionList("Right Hand"); - proofOfExceptionList("Right Hand"); + proofOfExceptionList( + "Right Hand"); }, child: SvgPicture.asset( "assets/svg/RH_1.svg", @@ -1360,7 +1404,8 @@ class _BiometricCaptureScanBlockPortraitState .exceptionType = ""; } updateExceptionList("Right Hand"); - proofOfExceptionList("Right Hand"); + proofOfExceptionList( + "Right Hand"); }, child: SvgPicture.asset( "assets/svg/RH_2.svg", @@ -1451,7 +1496,8 @@ class _BiometricCaptureScanBlockPortraitState .exceptionType = ""; } updateExceptionList("Right Hand"); - proofOfExceptionList("Right Hand"); + proofOfExceptionList( + "Right Hand"); }, child: SvgPicture.asset( "assets/svg/RH_3.svg", @@ -1542,7 +1588,8 @@ class _BiometricCaptureScanBlockPortraitState .exceptionType = ""; } updateExceptionList("Right Hand"); - proofOfExceptionList("Right Hand"); + proofOfExceptionList( + "Right Hand"); }, child: SvgPicture.asset( "assets/svg/RH_4.svg", diff --git a/pigeon/biometrics.dart b/pigeon/biometrics.dart index 6a070e169..fa24a0d9e 100644 --- a/pigeon/biometrics.dart +++ b/pigeon/biometrics.dart @@ -24,6 +24,12 @@ abstract class BiometricsApi { @async int getBioAttempt(String fieldId, String modality); + @async + String startOperatorOnboarding(); + + @async + String saveOperatorBiometrics(); + @async String addBioException(String fieldId, String modality, String attribute);