diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 9dec8d89fd..fbd16a706f 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -1,28 +1,34 @@ - # **CI/CD Implementation** ## **CI Workflow** -The CI Workflow is responsible for ensuring the quality of code changes before they are merged into the main branch. It performs the following tasks: - -1. **Unit Testing:** Executes unit tests for all modules to ensure new code does not break existing functionality. This helps identify and fix bugs early in the development process. +The CI Workflow is responsible for ensuring the quality of code changes before they are merged into the main branch. It performs the +following tasks: -2. **Code Quality Analysis:** Runs SonarQube analysis to identify code quality issues and potential bugs. This helps maintain high code standards and prevent future problems. +1. **Unit Testing:** Executes unit tests for all modules to ensure new code does not break existing functionality. This helps identify and + fix bugs early in the development process. +2. **Code Quality Analysis:** Runs SonarQube analysis to identify code quality issues and potential bugs. This helps maintain high code + standards and prevent future problems. **Workflow Trigger and Jobs** The CI Workflow is triggered by two events: -1. **Manual Trigger:** The workflow can be manually triggered through workflow dispatch, allowing developers to initiate the CI process on demand. - -2. **PR Changes:** The workflow is also triggered when a pull request (PR) is created or updated. This ensures that code changes are automatically tested and analyzed before being merged into the main branch. +1. **Manual Trigger:** The workflow can be manually triggered through workflow dispatch, allowing developers to initiate the CI process on + demand. +2. **PR Changes:** The workflow is also triggered when a pull request (PR) is created or updated. This ensures that code changes are + automatically tested and analyzed before being merged into the main branch. -The CI Workflow consists of 8 unit testing jobs plus the SonarQube scanning job. The unit testing jobs run in parallel, each responsible for testing a specific module or group of modules. The SonarQube scanning job waits until all the unit testing jobs are completed, the XML test coverage reports are uploaded, and then starts the sonar scan. +The CI Workflow consists of 8 unit testing jobs plus the SonarQube scanning job. The unit testing jobs run in parallel, each responsible for +testing a specific module or group of modules. The SonarQube scanning job waits until all the unit testing jobs are completed, the XML test +coverage reports are uploaded, and then starts the sonar scan. ## **CD Workflow** + Deployment Workflow Diagram: + ```mermaid flowchart TD trigger([Manual Trigger]) --> setup(Release Setup) @@ -50,39 +56,47 @@ flowchart TD deploy_dev --> deploy_firebase_dev(Upload to Firebase Dev) end ``` + **Trigger** -The CD Workflow can be manually triggered through workflow dispatch on a **release** branch. +The CD Workflow can be manually triggered through workflow dispatch on a **release** branch. **Environments** The CD Workflow is responsible for automatically deploying new code changes to different environments. It performs the following tasks: -1. **Deployment to Dev Environment:** Deploys the latest development build to the Firebase distribution account, making it accessible for testing and development purposes. - -2. **Deployment to Staging Environment:** Deploys the latest staging build to the Firebase distribution account, allowing a wider group of users to test the application before release. - -3. **Deployment to Internal Environment:** Deploys the latest release build to the internal testing track, providing a final testing phase before deployment to production. +1. **Deployment to Dev Environment:** Deploys the latest development build to the Firebase distribution account, making it accessible for + testing and development purposes. -4. **Promotion to Google Play Tracks:** Promotes the release build to different Google Play tracks in a controlled manner, starting with alpha and gradually progressing to the production track. +2. **Deployment to Staging Environment:** Deploys the latest staging build to the Firebase distribution account, allowing a wider group of + users to test the application before release. +3. **Deployment to Internal Environment:** Deploys the latest release build to the internal testing track, providing a final testing phase + before deployment to production. +4. **Promotion to Google Play Tracks:** Promotes the release build to different Google Play tracks in a controlled manner, starting with + alpha and gradually progressing to the production track. **Version Code** The version code is generated from 3 things: -1. A "base" version code of `10000000`. For a time the version code was derived from unix time / 1000. This created a always increasing number, but was otherwise not so useful. Setting a base allows us to establish a clean "floor" for the version code. If the workflow runs ever exceed the base, first of all go us, and 2nd the base can be removed. -2. The `run number` of the workflow. This tells us which run a build came from and is auto incrementing. -3. The last two digits are reserved for the `run attempts`. This tells us how many times a specific workflow was run. If more than 99 attempts are made (something is wrong) the build will fail and you need to start a new workflow run. -- Ex: `100001502` means this build came from workflow 15, run 2. +1. A "base" version code of `10000000`. For a time the version code was derived from unix time / 1000. This created a always increasing + number, but was otherwise not so useful. Setting a base allows us to establish a clean "floor" for the version code. If the workflow runs + ever exceed the base, first of all go us, and 2nd the base can be removed. +2. The `run number` of the workflow. This tells us which run a build came from and is auto incrementing. +3. The last two digits are reserved for the `run attempts`. This tells us how many times a specific workflow was run. If more than 99 + attempts are made (something is wrong) the build will fail and you need to start a new workflow run. + +- Ex: `100001502` means this build came from workflow 15, run 2. **Version Name** The version name follows our versioning convention: + - `year`.`quarter`.`release`-`(optional) deployment`+`run number`.`run attempt` -The optional params are **only** used on none release builds. +The optional params are **only** used on none release builds. - Ex: `2024.1.0-dev+15.2`, Quarter 1 of 2024, dev deployment, time, run 15, attempt 2 - Ex: `2024.1.0+15.2`, Quarter 1 of 2024, release, run 15, attempt 2 @@ -91,4 +105,5 @@ Note: The `year`.`quarter`.`release` is take from the branch name. Ex: `release/ ## **Dependency Updates workflow** -Updates project dependencies using Dependabot, an automated dependency management tool, ensuring that the project always uses the latest stable versions of its dependencies. +Updates project dependencies using Dependabot, an automated dependency management tool, ensuring that the project always uses the latest +stable versions of its dependencies. diff --git a/README.md b/README.md index eb5f4d9109..db7d83083d 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,10 @@ # Android-Simprints-ID -## Architecture +## Technical documentation -The goal of Simprints Architecture is to keep the app maintainable, scalable, easy to work on by multiple people and teams simultaneously, and most importantly - simple. **This architecture is a work in progress, it reflects the planned future state of the repo, it does not reflect its current setup.** - -### Modules - -There are 2 types of modules we can use, a Feature Module and a Infrastructure Module, with a 3rd type which is the App Module of which there will only ever be 1 of (the ID module). This design has been adopted in several places, and there is even a guide you can check out [here](https://dev.to/noureldinshobier/building-scalable-flutter-apps-architecture-styling-conventions-state-management-40c9) that loosely breaks down a similar architecture. But keep in mind it’s not identical. Following this breakdown a very simple application comprised of a login screen could look like this: - -- App (app module) -- feature login (login UI/UX) -- infra login (login infrastructure code) -- infra networking (networking infrastructure code) - -### Feature Modules - -Feature modules contain the logical boundaries for the user interaction components of a given feature in SID. For example these modules will contain the activities, fragments, views, layouts, and navigation components of a specific feature in SID. They should not contain reusable business logic, or things relating to infrastructure outside of the UX of the feature, those should all be inside of infrastructure modules. You might have two identically themed modules because of this which is fine. For example you could have a Remote Config feature module, which contains the screens and components that interact with the user, and a Remote Config infrastructure module, which contains the infrastructure for fetching, updating and storing the remote configuration. Feature modules will have a couple rules: - -Rules: -- Feature modules can depend on the App Module (if they’re a dynamic feature module) and any number of infrastructure modules, but they cannot depend on other feature modules. - - *Note: The circular dependency between DFMs and the App module is baked into the system for some reason. This is not a logic/design based dependency. Melad is going to explore this on a future learning day.* -- Feature modules are accountable for their own internal navigation (they should use a [nested nav graph](https://developer.android.com/guide/navigation/navigation-design-graph#nested-graphs)) and the back stack for their UI. They should have a single point of entry and exit. -- Feature modules can be a [dynamic feature module](https://developer.android.com/guide/playcore/feature-delivery/on-demand) or a normal Android module, depending on its delivery needs. - -### Infrastructure Modules - -Infrastructure Modules contain business logic that should be logically isolated for cleanliness and re-use. Unlike feature modules they should be completely unaware of any UX components such as UIs or navigation. Their goal is to encapsulate some part of the domain layer of the application and make it re-usable to other components. Infrastructure modules will have a couple rules: - -Rules: -- Infrastructure modules should have a single access point which is the contract for the behavior of the module. This should be a top level interface file that exposes the functionality of the module. All other files (except those related to building) should be marked internal and not exposed to its users. -- Infrastructure modules will depend on the builder pattern. There will be two top level nome inner classes, the interface the exposes the functionality, and the builder object that is able to build the implementation of that interface. Say for the *infralogin* module we have a *LoginManager* interface we'd also have a top level *LoginManagerBuilder* class which is able to build the required implementation of that interface. It doesn't matter what that builder itself uses for DI (such as dagger ), and same for the other builders that call it. -- Infrastructure modules can’t depend on feature modules or the App module, but they can depend on other infrastructure modules (keep in mind the dependencies can’t be circular). -- Infrastructure modules preferably are raw Java modules, but they can be Android modules if they need access to certain android components. This is fine for modules that use Jetpack components like Room or Datastore, but they cannot use any components relating to user interactions, such as Activities, Fragments, UI/Layout, or navigation components. - -### The App Module - -In general you don’t have to worry about this section as there can only be one app module (called ID) which is the top level Android Application module. It’s role is to expose the Android manifest, do the initial navigation of the app and house the main Application class. - -Rules: -- The app module should not contain any major business or domain logic, it should just be a thin layer to handle the app navigation and any Android specific requirements such as declaring the apps min API level, etc. - -### SID Breakdown - -Following the guidelines above the end goal of SID should look roughly like: - -- featureabout (com.simprints.feature.about) -- featureclientapi (com.simprints.feature.clientapi) -- featuredashboard (com.simprints.feature.dashboard) -- featureface (com.simprints.feature.face) -- featurefingerprint (com.simprints.feature.fingerprint) -- featurelogin (com.simprints.feature.login) -- featuresyncinfo (com.simprints.feature.syncinfo) -- id -- infraconfig (com.simprints.infra.config) -- infraenrolmentrecords (com.simprints.infra.enrolment.records) -- infraevents (com.simprints.infra.events) -- infrafacematcher_roc (com.simprints.infra.facematcher) -- fingerprint/infra/matcher (com.simprints.fingerprint.infra.matcher) -- fingerprint/infra/scanner (com.simprints.fingerprint.infra.scanner) -- fingerprint/infra/scannermock (com.simprints.fingerprint.infra.scannermock) -- infraimages (com.simprints.infra.images) -- infralicense (com.simprints.infra.license) -- infralogging (com.simprints.infra.logging) -- infralogin (com.simprints.infra.login) -- infranetwork (com.simprints.infra.networking) -- infrarealm (com.simprints.infra.enrolment.records.realm.store) -- infrasecurity (com.simprints.infra.security) - -*Note: There is no longer a core module. There should be no "catch all" module, because it will just become a graveyard / completely overused, like the previous ID module. Every module should have a clear singular purpose.*
- -
+A high level documentation on how each module works can be found in +the [project's wiki](https://simprints.gitbook.io/docs/architecture/system-architecture/mobile/simprints-id-sid). +More details about each feature or how each module work can be seen inside every module README files or inside respective folders. ## Development setup @@ -113,27 +48,26 @@ Replace `` and `` with your ac For security reasons, some files are not included in the repository. You must download them separately: -1. Download the necessary files from the internal [SID Development Resources folder](https://drive.google.com/drive/folders/1OLrGhx3AW91ab2zduy8FzNuE5r5VEs7g?usp=drive_link). **Note:** This link is accessible to Simprints employees only. +1. Download the necessary files from the + internal [SID Development Resources folder](https://drive.google.com/drive/folders/1OLrGhx3AW91ab2zduy8FzNuE5r5VEs7g?usp=drive_link). + - **Note:** This link is accessible to Simprints employees only. 2. Place the downloaded files as follows: - - `signing_info.gradle.kts`: Place this in the `build-logic` directory. - - `debug.keystore`: Place this in the root directory of the project. - - `google-services.json`: Place this in the `id/src` directory. + - `signing_info.gradle.kts`: Place this in the `build-logic` directory. + - `debug.keystore`: Place this in the root directory of the project. + - `google-services.json`: Place this in the `id/src` directory. ### 5. Build and Run the App Open the project in Android Studio, sync the project with Gradle files, and then build and run the app on your connected device or emulator. - ## Full CI Workflow -The aim of the `ci` workflow is to run all tests in all modules, assemble production and debug -builds of the APK, and report to the main CI Slack channel. +The aim of the `ci` workflow is to run all tests in all modules, assemble production and debug builds of the APK, and report to the main CI +Slack channel. When run, it immediately triggers all the other relevant workflows such that all tests are run. -In the mean-time, the `ci` build waits for the other workflows to finish and, if they pass, continue -to the assemble and deploy steps. +In the mean-time, the `ci` build waits for the other workflows to finish and, if they pass, continue to the assemble and deploy steps. -It is triggered upon pull requests and serves as validation of the integrity of the branch for any -pull requests into `main`. +It is triggered upon pull requests and serves as validation of the integrity of the branch for any pull requests into `main`.
@@ -142,12 +76,8 @@ pull requests into `main`. ### How to run tests To run all tests in all modules, run `./gradlew testDebugUnitTest` from the root directory. -To run test for a specific module, run `./gradlew moduleName:testDebugUnitTest` for example to run tests for the id module run `./gradlew id:testDebugUnitTest` - -### Technical documentation on features - -A high level documentation on how each module works can be found in the [project's wiki](https://simprints.gitbook.io/docs/architecture/system-architecture/mobile/simprints-id-sid). -More details about each feature or how each module work can be seen inside every module README files or inside respective folders. Higher level features that touch all modules are documented in the [id module](id/README.md). +To run test for a specific module, run `./gradlew moduleName:testDebugUnitTest` for example to run tests for the id module run +`./gradlew id:testDebugUnitTest`
@@ -156,18 +86,20 @@ More details about each feature or how each module work can be seen inside every Simprints ID has 3 different build types: `debug`, `staging` and `release`. - `debug`: to be used only in development. Uses the development environment of the backend -- `staging`: to be used only for pre-release internal tests. Uses the staging environment of the backend, and can be used to test production builds both locally and on the Playstore internal channel +- `staging`: to be used only for pre-release internal tests. Uses the staging environment of the backend, and can be used to test production + builds both locally and on the Playstore internal channel - `release`: to be used only in production. Uses the production environment of the backend ## Building the app (command line) + The examples below will show how to create app bundles using `./gradlew`. To create apks, use the `assemble` command instead of `bundle`. -| Command | DEBUG_MODE | Encrypted DBs | Logging | Debug Features (i.e debug activity) | Backend | -|---------------------------|-----------------|----------------|-------------|-------------------------------------|----------------------------------------| -| `bundleDebug` | ✓ | x | ✓ | ✓ | development | -| `bundleStaging` | ✓ | x | ✓ | ✓ | staging | -| `bundleRelease` | x | ✓ | x | x | production (CI only) | +| Command | DEBUG_MODE | Encrypted DBs | Debug Features (i.e debug activity) | Backend | +|-----------------|------------|---------------|-------------------------------------|----------------------| +| `bundleDebug` | ✓ | x | ✓ | development | +| `bundleStaging` | ✓ | x | ✓ | staging | +| `bundleRelease` | x | ✓ | x | production (CI only) |
@@ -175,13 +107,13 @@ To create apks, use the `assemble` command instead of `bundle`. To create an universal apk that can be shared you need to: -1. Create a bundle of the app -`./gradlew clean bundleDebug` +1. Create a bundle of the app `./gradlew clean bundleDebug` 2. Create a universal apk that can be installed in any device (warning: this is a big app) -`bundletool build-apks --bundle=id/build/outputs/bundle/debug/id-debug.aab --output=id-debug.apks --ks=debug.keystore --ks-pass=pass:android --ks-key-alias=androiddebugkey --mode=universal --overwrite` + `bundletool build-apks --bundle=id/build/outputs/bundle/debug/id-debug.aab --output=id-debug.apks --ks=debug.keystore --ks-pass=pass:android --ks-key-alias=androiddebugkey --mode=universal --overwrite` -To install [bundletool](https://github.com/google/bundletool) you can download the jar from Github and execute it using `java -jar bundletool` or install using Homebrew (on macOS). +To install [bundletool](https://github.com/google/bundletool) you can download the jar from Github and execute it using +`java -jar bundletool` or install using Homebrew (on macOS).
diff --git a/SECURITY.md b/SECURITY.md index 7ccc4da142..08ac522cf5 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,24 +2,29 @@ ## Supported Versions -| Version | Supported | -| ------- | ------------------ | -| 2023.4.0| :white_check_mark: | - +| Version | Supported | +|----------|--------------------| +| 2023.4.5 | :white_check_mark: | +| 2024.1.4 | :white_check_mark: | +| 2024.2.2 | :white_check_mark: | +| 2025.1.0 | :white_check_mark: | ## Reporting a Vulnerability -Please report any security vulnerabilities you find in Android-Simprints-ID to [our email address](securityreport@simprints.com). We appreciate your help in keeping Android-Simprints ID secure! +Please report any security vulnerabilities you find in Android-Simprints-ID to [our email address](securityreport@simprints.com). We +appreciate your help in keeping Android-Simprints ID secure! Here's what you can expect when you report a vulnerability: -Review: We will review all reported vulnerabilities. -Response: You will receive an initial response acknowledging your report. -Acceptance/Decline: We will let you know whether we accept the vulnerability as a valid security issue at the earliest opportunity. -Fix and Release: If we accept the vulnerability, we will work to fix it and release a patch as soon as possible. -Credits: We will publicly credit you for finding the vulnerability unless you request otherwise. -Additional Information: +* **Review:** We will review all reported vulnerabilities. +* **Response:** You will receive an initial response acknowledging your report. +* **Acceptance/Decline:** We will let you know whether we accept the vulnerability as a valid security issue at the earliest opportunity. +* **Fix and Release:** If we accept the vulnerability, we will work to fix it and release a patch as soon as possible. +* **Credits:** We will publicly credit you for finding the vulnerability unless you request otherwise. + +## Additional Information: You can also report security vulnerabilities through the security page on the GitHub repository. -For more information on our security practices, please see our Security pages on our [documentation site](https://simprints.gitbook.io/docs/security-and-privacy/security-and-privacy-considerations). +For more information on our security practices, please see our Security pages on +our [documentation site](https://simprints.gitbook.io/docs/security-and-privacy/security-and-privacy-considerations). diff --git a/face/README.md b/face/README.md new file mode 100644 index 0000000000..532491fe51 --- /dev/null +++ b/face/README.md @@ -0,0 +1,27 @@ +# Face modality + +The face modality was created as a way to have contactless biometrics as an option for SimprintsID. + +## Flow overview + +This first thing that the face capture needs to do is initialize the required SDK, loading the SDK library and making sure the SDK license +is in place and is valid. + +To understand more how the capture flow works, check the capture [README](capture/README.md). + +## Detection + +The detection phase is when the app analyzes the (already cropped by `CropToTargetOverlayAnalyzer`) and returns a Face that it +found (or null if none). + +Note that the Face returned also have a template already in it, making it a one step to find a face and extract the template for the app. +It was done that way because most SDKs tested returned a template when looking for a face. + +## RankOne + +RankOne is the SDK of choice for face recognition - after we did some extensive testing with lots of other providers. +RankOne gives an SDK to copy to inside Simprints. It lives inside the respective infra module. + +Current RankOne versions are + * 1.23 for legacy projects + * 3.1 for all new projects diff --git a/face/capture/README.md b/face/capture/README.md index 368830201b..c4609a1a8e 100644 --- a/face/capture/README.md +++ b/face/capture/README.md @@ -1,34 +1,43 @@ -# Face modality +# Capture Flow -The face modality was created as a way to have contactless biometrics as an option for SimprintsID. +This is how the face module works internally to capture the faces, extract the templates, and return the results to SimprintsID. -## Important links +## FaceCaptureControllerFragment -* [Confluence](https://simprints.atlassian.net/wiki/spaces/CS/overview) -* [Jira](https://simprints.atlassian.net/secure/RapidBoard.jspa?rapidView=19) +The shared fragment (and its ViewModel) is responsible for: -## Flow overview +- Checking that the correct parameters were sent from calling module for a correct capture +- Start the internal Navigation Graph +- Managing the next steps of the navigation by using events and the Navigation Graph +- Saving the captures on disk once the flow is finished correctly +- Finish the flow correctly and return the correct result to calling module -Calling module start the face modality navigating with `FaceCaptureControllerFragmentArgs` as bundle. -This first thing that the face capture needs to do is initialize the required SDK, loading the SDK library and making sure the SDK license is in place and is valid. +## When the flow finishes correctly -To understand more how the capture flow works, check the capture [README](src/main/java/com/simprints/face/capture/README.md). +The FaceCaptureViewModel receives all captures and saves the valid ones on disk. -## Detection +## PreparationFragment -The detection phase is when the app analyzes a PreviewFrame (already cropped by FrameProcessor) and returns a Face that it found (or null if none). -The methods on the Detectors are suspend functions because the process to get a Face can be onerous (you should use `withContext(Dispatchers.IO)`). -Note that the Face returned also have a template already in it, making it a one step to find a face and extract the template for the app. -It was done that way because most SDKs tested returned a template when looking for a face. Currently we only use the analyze method that receives a `PreviewFrame`, -the method to analyze a `Bitmap` is there for future necessity (it was used by the R&D team). +It is a simple fragment where the user sees a preparation on how to capture a good face image. Its only responsibility is to show the +message and start the LiveFeedbackFragment. -### MockFaceDetector +## LiveFeedbackFragment -This is a mock detector that always return true and wait a bit (200ms) before returning a face with an empty template. +The responsibility of this fragment (and its ViewModel) is to make sure the user receives correct information on the state of the face on +the screen, i.e. if the face is valid or not and how to fix it. +This fragment is also responsible to start the camera and handle the frames being passed downstream from our camera library. -## RankOne +The FaceCaptureViewModel has a channel that starts receiving frames when the camera starts. The LiveFeedbackFragment subscribe to that +channel and process each frame. -RankOne is the SDK of choice for face recognition - after we did some extensive testing with lots of other providers. -RankOne gives an SDK to copy to inside Simprints. It lives inside the respective infra module. +If the face is valid, the fragment will prompt the user to start a capture and at that time will start saving each new frame as a capture. +After the number of required captures is done, the fragment finishes and goes to the ConfirmationFragment. -Current RankOne version = 1.23 (with OpenMP disabled) +During the live feedback process, while the user is trying to center the face on the frame, the ViewModel will keep any good image as a +fallback image. This is to make sure that the user always has at least one good image, even if they move the phone too fast during the +capture process. + +## ConfirmationFragment + +If all goes well, the user comes to a screen that congratulates them on taking a good photo and ask them to continue their flow. +If the previewed captures are not satisfactory, user can return to the LiveFeedbackFragment and try again. diff --git a/face/capture/src/main/java/com/simprints/face/capture/README.md b/face/capture/src/main/java/com/simprints/face/capture/README.md deleted file mode 100644 index 3aca298c9f..0000000000 --- a/face/capture/src/main/java/com/simprints/face/capture/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# Capture Flow - -This is how the face module works internally to capture the faces, extract the templates, and return the results to SimprintsID. - -## FaceCaptureControllerFragment - -The shared fragment (and its ViewModel) is responsible for: -- Checking that the correct parameters were sent from calling module for a correct capture (number of samples to capture, sessionId, projectId) -- Start the internal Navigation Graph -- Managing the next steps of the navigation by using events and the Navigation Graph -- Saving the captures on disk once the flow is finished correctly -- Finish the flow correctly and return the correct result to calling module - -## When the flow finishes correctly - -The FaceCaptureViewModel receives all captures and saves the valid ones on disk. - -## PreparationFragment - -It is a simple fragment where the user sees a preparation on how to capture a good face image. Its only responsibility is to show the message and start the LiveFeedbackFragment. - -## LiveFeedbackFragment - -The responsibility of this fragment (and its ViewModel) is to make sure the user receives correct information on the state of the face on the screen, i.e. if the face is valid or not and how to fix it. -This fragment is also responsible to start the camera and handle the frames being passed downstream from our camera library. - -The FaceCaptureViewModel has a channel that starts receiving frames when the camera starts. The LiveFeedbackFragment subscribe to that channel and process each frame. - -If the face is valid, the fragment will prompt the user to start a capture and at that time will start saving each new frame as a capture. -After the number of required captures is done, the fragment finishes and goes either to a ConfirmationFragment or RetryFragment. - -During the live feedback process, while the user is trying to center the face on the frame, the ViewModel will keep any good image as a fallback image. -This is to make sure that the user always has at least one good image, even if they move the phone too fast during the capture process. This should render the RetryFragment unreachable. - -## RetryFragment - -If the user can retry the flow, they will come to a fragment that tells a bit more about the problem and how to solve it. -Usually the same steps they should take to take a good capture. After that, they return to LiveFeedbackFragment to try again. - -After several tries, if the user still can’t take a good photo, the fragment will show some error message and return to SimprintsID an exit error. - -## ConfirmationFragment - -If all goes well, the user comes to a screen that congratulates them on taking a good photo and ask them to continue their flow. diff --git a/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedback/README.md b/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedback/README.md index dc73888515..11abf7f8bb 100644 --- a/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedback/README.md +++ b/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedback/README.md @@ -5,20 +5,3 @@ The main auxiliary tools for capture a good image is CameraTargetOverlay and Fra ## CameraTargetOverlay This is the overlay that is painted on top of the camera (in `LiveFeedbackFragment`) and specify the area that the SDK will look into to check for a face. -Currently it has a size of 240dp that is used as the size for `DashedCircularProgress` in `fragment_live_feedback.xml`. -There was no other way of setting that size and synchronizing between both components and `FrameProcessor`, that is why it is inside this class. -The overlay is drawn only once, when `drawSemiTransparentTarget` or `drawWhiteTarget` is called. - -## FrameProcessor - -The most important piece of code, this class: -- create a rotated rectangle based on the current orientation of the camera -- resize the new rectangle if the image on the screen has some crop in it -- create a new box based on the new rectangle -- crop the frame using just the new rectangle - -All those steps are necessary because cameras on Android are usually rotated or even flipped (front face camera). -Also, what is shown on the screen and the real frame are not the same image, sometimes some cropping might be occurring (e.g. the phone has 16:9 aspect ratio but the photo is 16:10). - -Note that this class uses `CameraTargetOverlay.rectForPlane`, which internally uses `percentFromTop`. If the overlay is changed (or a new one is used), the FrameProcessor might need to be adjusted. -This was done because there is no way of knowing where the overlay is on the screen by other means. diff --git a/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedbackautocapture/README.md b/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedbackautocapture/README.md index 52a0893b97..f5def99d18 100644 --- a/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedbackautocapture/README.md +++ b/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedbackautocapture/README.md @@ -1,10 +1,17 @@ # Face auto-capture -This `livefeedbackautocapture` package is similar to the manual capture [livefeedback](../livefeedback/README.md) one, except: -* Auto-capture has a preparation period from the moment `LiveFeedbackAutoCaptureFragment` becomes visible and for `LiveFeedbackAutoCaptureFragmentViewModel.AUTO_CAPTURE_VIEWFINDER_RESUME_DELAY_MS` amount of time. This helps prevent startling the user with a too early start of auto-capture - before the user would aim the viewfinder at a face. -* The auto-capture imaging progress starts when a qualifying face image appears in the viewfinder, and lasts for `LiveFeedbackAutoCaptureFragmentViewModel.AUTO_CAPTURE_IMAGING_DURATION_MS` amount of time. -* The number of images to accept is `LiveFeedbackAutoCaptureFragmentViewModel.samplesToKeep` - similarly to `LiveFeedbackFragmentViewModel.samplesToCapture`. The best quality sampled images are selected to keep. -* The kept sampled images and the fallback image are included in the capture events - unlike in `LiveFeedbackFragmentViewModel` where all conventionally captured and the fallback images are included. +This `livefeedbackautocapture` package is similar to the manual capture livefeedback one, except: + +* Auto-capture has a preparation period from the moment `LiveFeedbackAutoCaptureFragment` becomes visible and for + `LiveFeedbackAutoCaptureFragmentViewModel.AUTO_CAPTURE_VIEWFINDER_RESUME_DELAY_MS` amount of time. This helps prevent startling the user + with a too early start of auto-capture - before the user would aim the viewfinder at a face. +* The auto-capture imaging progress starts when a qualifying face image appears in the viewfinder, and lasts for + `LiveFeedbackAutoCaptureFragmentViewModel.AUTO_CAPTURE_IMAGING_DURATION_MS` amount of time. +* The number of images to accept is `LiveFeedbackAutoCaptureFragmentViewModel.samplesToKeep` - similarly to + `LiveFeedbackFragmentViewModel.samplesToCapture`. The best quality sampled images are selected to keep. +* The kept sampled images and the fallback image are included in the capture events - unlike in `LiveFeedbackFragmentViewModel` where all + conventionally captured and the fallback images are included. * The capture events have an `isAutoCapture` flag value of `true`. -The reason for having this package as a near-copy of `livefeedback` is to keep both implementations independent but similar. The layout for `LiveFeedbackAutoCaptureFragment` is `fragment_live_feedback_auto_capture.xml`. +The reason for having this package as a near-copy of `livefeedback` is to keep both implementations independent but similar. The layout for +`LiveFeedbackAutoCaptureFragment` is `fragment_live_feedback_auto_capture.xml`. diff --git a/face/infra/base-bio-sdk/README.md b/face/infra/base-bio-sdk/README.md index 9e5d697dbe..0c826b86aa 100644 --- a/face/infra/base-bio-sdk/README.md +++ b/face/infra/base-bio-sdk/README.md @@ -4,9 +4,9 @@ This is a base module that allows users to integrate new Face SDKs into SID's Fa To use this base module, simply add the base module to your new SDK module's dependencies and then let your new module provide and implement the operations in -1. [`FaceBioSdkInitializer`](src/main/java/com/simprints/infra/face.basebiosdk/initialization/FaceBioSdkInitializer.kt) -2. [`FaceDetector`](src/main/java/com/simprints/infra/face.basebiosdk/detection/FaceDetector.kt) -3. [`FaceMatcher`](src/main/java/com/simprints/infra/face.basebiosdk/matching/FaceMatcher.kt) +1. [`FaceBioSdkInitializer`](src/main/java/com/simprints/face/infra/basebiosdk/initialization/FaceBioSdkInitializer.kt) +2. [`FaceDetector`](src/main/java/com/simprints/face/infra/basebiosdk/detection/FaceDetector.kt) +3. [`FaceMatcher`](src/main/java/com/simprints/face/infra/basebiosdk/matching/FaceMatcher.kt) Here is an example on how to provide the there implemented classes ```kotlin diff --git a/face/infra/roc-v1/README.md b/face/infra/roc-v1/README.md index 1dd1fc444d..cf0df018c4 100644 --- a/face/infra/roc-v1/README.md +++ b/face/infra/roc-v1/README.md @@ -1,4 +1,5 @@ # ROC V1 -This module provides a wrapper for accessing all ROC SDK APIs. -It implements all operations in `:face:infra:base-bio-sdk` module and provides the implemented classes in `RocWrapperModule`. +This module provides a wrapper for accessing all ROC v1.23 SDK APIs. + +It implements all operations in `:face:infra:base-bio-sdk` module and provides the implemented classes in `RocV1WrapperModule`. diff --git a/face/infra/roc-v3/README.md b/face/infra/roc-v3/README.md index 10c99833cb..a779c1ed39 100644 --- a/face/infra/roc-v3/README.md +++ b/face/infra/roc-v3/README.md @@ -1,4 +1,4 @@ # ROC V3 -This module provides a wrapper for accessing all ROC SDK V3.1 APIs. -It implements all operations in `:face:infra:base-bio-sdk` module and provides the implemented classes in `RocWrapperModule`. +This module provides a wrapper for accessing all ROC SDK v3.1 APIs. +It implements all operations in `:face:infra:base-bio-sdk` module and provides the implemented classes in `RocV3WrapperModule`. diff --git a/feature/matcher/README.md b/feature/matcher/README.md index 37c7bc08c4..de42784a67 100644 --- a/feature/matcher/README.md +++ b/feature/matcher/README.md @@ -1,13 +1,13 @@ # How matching works -Calling feature module provides `MatchParams` in navigation arguments with a list of -either `FaceSample` or `FingerprintSample` and a query to load the candidates from the database. +Calling feature module provides `MatchParams` in navigation arguments with a list of either `FaceSample` or `FingerprintSample` and a query +to load the candidates from the database. -Matching needs to compare the probes templates with all the candidates templates and return a list -of X candidates sorted descending by their higher comparison scores. +Matching needs to compare the probes templates with all the candidates templates and return a list of X candidates sorted descending by +their higher comparison scores. -- Sample list is provided because the Capture flow can return more than one capture (depending on - the configuration). Each probe has its own template. +- Sample list is provided because the Capture flow can return more than one capture (depending on the configuration). Each probe has its own + template. - Each candidate have a guid and a list of samples. What this means is that the number of comparisons will be: @@ -16,21 +16,17 @@ What this means is that the number of comparisons will be: p * c * cs ``` -p - number of probes -c - number of candidates -cs - number of samples per candidate +p** - number of probes, **c** - number of candidates, **cs** - number of samples per candidate Example: if the configuration say that each capture has 2 samples, and the database already has 3 people, 12 comparisons will be made (2 * 3 * 2). ## Sorting the comparison scores -For response, calling module expects a MatchResult with a list of a guid and confidence score pairs. -This means that no matter how many samples the candidate has, only the highest comparison score will -be return. +For response, calling module expects a MatchResult with a list of a guid and confidence score pairs. This means that no matter how many +samples the candidate has, only the highest comparison score will be return. -What is being done is during a comparison of probes against a candidate, only the highest score of -all is kept and added to the MatchResult. +What is being done is during a comparison of probes against a candidate, only the highest score of all is kept and added to the MatchResult. Example: @@ -50,7 +46,6 @@ the `mean` down as (1 + 0) / 2 = 0.5. # Concurrency -Because the process of matching can be expensive - it needs to match `n` probes against `f` -candidate faces - we tried to run it in parallel. That way, we can run multiple matching at the -same time. Also, since the list will be ordered later, we don't need to care about the order that -the results are returned as well. +Because the process of matching can be expensive - it needs to match `n` probes against `f` candidate faces - we tried to run it in batches +in parallel. +That way, we can run multiple matching at the same time. Also, to reduce memory pressure the results are stored in a limited sorted tree. diff --git a/fingerprint/README.md b/fingerprint/README.md new file mode 100644 index 0000000000..f3068f9691 --- /dev/null +++ b/fingerprint/README.md @@ -0,0 +1,20 @@ +# Fingerprint Modality Module + +This is the main module for the fingerprint modality in Simprints ID. + +### Further READMEs + +The main domain sub-packages are: + +- [Connection](connect/README.md) \- which handles connection to the scanner. +- [Capture](capture/README.md) \- which handles fingerprint capture UI flow. +- [Scanner](infra/scanner/README.md) + \- which handles high-level interfacing with the `fingerprint:infra:scanner` module for using a Vero fingerprint scanner. +- Various biometric SDK related modules + +The satellite libraries of the fingerprint modality that are used in this module are: + +- [`fingerprint:infra:scanner`](infra/scanner/README.md) + \- which handles low-level communication with the fingerprint scanner and tucks it behind a `Scanner` class abstraction. +- [`fingerprint:infra:scannermock`](infra/scannermock/README.md) + \- which is a utility package providing mocking and simulation options for the fingerprint scanner for testing and debugging. diff --git a/fingerprint/capture/README.md b/fingerprint/capture/README.md index 89031c1ad9..69cf018708 100644 --- a/fingerprint/capture/README.md +++ b/fingerprint/capture/README.md @@ -1,20 +1,13 @@ -# Fingerprint Modality Module +# Fingerprint capture -This is the main module for the fingerprint modality in Simprints ID. +This is how the fingerprint module works internally to capture the fingerprints, extract the templates, and return the results to +SimprintsID. -### Further READMEs +## FingerprintCaptureFragment -The main domain sub-packages are: +This fragment is the entry point into the fingepringt capture flow and it is responsible for: -- [Connection](../connect/README.md) \- which handles connetion to the scanner. -- [Scanner](../infra/scanner/README.md) - \- which handles high-level interfacing with the `fingerprint:infra:scanner` module for using a Vero fingerprint scanner. - -The satellite libraries of the fingerprint modality that are used in this module are: - -- [`fingerprint:scanner`](../infra/scanner/README.md) - \- which handles low-level communication with the fingerprint scanner and tucks it behind a `Scanner` class abstraction. -- [`fingerprint:scannermock`](../infra/scannermock/README.md) - \- which is a utility package providing mocking and simulation options for the fingerprint scanner for testing and debugging. -- [`feature:module`](../../feature/matcher/README.md) - \- which houses the algorithms for matching fingerprints and provides an interface for their use. +- Launching scanner connection sub-flow +- Leading user over fingerprint capture step by step +- Saving captured fingerprint images if necessary +- Finishing the flow and reporting the capture results to the calling module diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/README.md b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/README.md deleted file mode 100644 index 240f6f4e5a..0000000000 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# CollectFingerprintsActivity - -This activity is the screen where the user scans fingerprint templates and images from the scanner. - -The activity starts by receiving which fingers to capture in the `CollectFingerprintsTaskRequest`. -Once complete, it will return a list of `Fingerprint`s if it finishes normally. -Note that the `Fingerprints` returned may differ from that fingers requested if fingers were skipped or auto-added due to bad scans. - -The activity UI centers around a `ViewPager` that holds `FingerFragment`s, with a `ScanningTimeoutBar` and button that get updated during the scanning flor. -The central state is stored as a `CollectFingerprintsState` by the view model, which is updated and re-posted whenever a change to the UI is to be made. -The appropriate UI is deduced mainly by retrieving from a map the current `FingerCollectionState`. -The view model also emits certain events peripherally. - -`ScannerManager` is expected to already have a connected and ready Vero. -When the activity is resumed, the scanner trigger button is effectively linked to the scan button (except when the confirmation dialog is shown in which case it's linked to the "OK" option). -Should the scanner disconnect during communication, the `ConnectScannerActivity` will be launched with the reconnect mode, which will appear as an overlay. -The scanner disconnects upon leaving the activity. - -`FingerprintCaptureEvent`s are saved in the current session for every scan. -If images were collected during the flow, they will be saved only when the activity finishes. - -Pressing back yield the `RefusalActvity`. Submitting the refusal form will propagate through the activity. -The `AlertActivity` can be launched if an unexpected error occurred during scanning. diff --git a/fingerprint/connect/README.md b/fingerprint/connect/README.md index 4bb01d9c9c..adfe98d7a4 100644 --- a/fingerprint/connect/README.md +++ b/fingerprint/connect/README.md @@ -1,41 +1,50 @@ # Connect Scanner This is the module that handles the setup with the scanner, and any associated issues that might occur. -The desired side-effect of this module is creating a connected instance of `Scanner` in the `ScannerManager` singleton, which can then be used by proceeding modules. +The desired side-effect of this module is creating a connected instance of `Scanner` in the `ScannerManager` singleton, which can then be +used by proceeding modules. -It is a nested nav-graph design using the [Navigation Architecture Component](https://developer.android.com/guide/navigation) to switch between fragments. +It is a nested nav-graph design using the [Navigation Architecture Component](https://developer.android.com/guide/navigation) to switch +between fragments. There is a shared view model for all fragments, `ConnectScannerViewModel`, which handles the setup flow with the scanner. The more complex fragments additionally have their own view models. The primary fragment is `ConnectScannerControllerFragment`. -This fragment acts as a container for either the `ConnectFragment` when it's launched for the first time during the flow. +This fragment acts as a container for the `ConnectFragment` when it's launched for the first time during the flow. During the setup flow several exceptions can be triggered by the `ScannerManager`. Most of these are turned into issue fragments, which represents a particular screen to show to the user for them to deal with. There is a fragment for each issue, and they can be launched from the main fragment during the flow and sometimes launch each other. Several specific case are handled by calling `:feature:alert` module.These are: + - `BLUETOOTH_NOT_SUPPORTED` - we didn't bother to update the UI for this as it's so rare (and inconceivable in production) - `LOW_BATTERY` - this can currently only be triggered by Vero 1, and in practice was never seen, so left as is - `UNEXPECTED_ERROR` - this occurs when an irrecoverable programmatic error has occurred -After connecting is successful or if the connection reached unrecoverable state, the `ConnectScannerControllerFragment` finishes with the appropriate result data. +After connecting is successful or if the connection reached unrecoverable state, the `ConnectScannerControllerFragment` finishes with the +appropriate result data. -Pressing the back button at any time triggers the exit form, and there should be no issue returning to the connection flow if the user changes their mind. +Pressing the back button at any time triggers the exit form, and there should be no issue returning to the connection flow if the user +changes their mind. ### BluetoothOffFragment + This can be launched at the start of the flow when bluetooth is off. The button programmatically turns bluetooth on. This makes use of the `BLUETOOTH_ADMIN` permission, which appears to be granted automatically upon install. -Returns to the `ConnectScannerMainFragment` upon finish. +Returns to the `ConnectFragment` upon finish. ### NfcOffFragment + This can be launched when we want to reach the `NfcPairIssue` but NFC is off on the device. -There is no way to programmatically turn on NFC, so an `Intent` is launched to the settings screen where NFC resides and we check upon resume if NFC is on. +There is no way to programmatically turn on NFC, so an `Intent` is launched to the settings screen where NFC resides and we check upon +resume if NFC is on. Always leads into the `NfcPairFragment` upon finish. ### ScannerOffFragment + This is launched after the user has confirmed the scanner's serial number but it can't be connected to. The default assumption is that it is off, so the user is prompted to turn it on. @@ -44,17 +53,22 @@ A "Try Again" button exists, but does nothing. The user is provided with a "link" in case we are trying to connect to the wrong scanner and got to this screen by accident. Upon successful connection, always directly finishes the activity. -If the user presses the "SPXX is not my scanner" link, this leads to the appropriate pairing fragment, which can be either `NfcOffFragment`, `NfcPairFragment`, or the `SerialEntryFragment`. +If the user presses the "SPXX is not my scanner" link, this leads to the appropriate pairing fragment, which can be either `NfcOffFragment`, +`NfcPairFragment`, or the `SerialEntryFragment`. Can also go to the other error fragments if an issue arises during connection, such as OTA. ### NfcPairFragment -This fragment is launched if the user confirms the wrong scanner is paired, if there are no scanners paired, or if there are multiple scanners paired. + +This fragment is launched if the user confirms the wrong scanner is paired, if there are no scanners paired, or if there are multiple +scanners paired. Additionally, this fragment is launched only on projects that are not using Vero 1 and only on devices that have an NFC adapter. Whilst started, detected NFC chips and reads them for the Simprints MAC address. -Once an NFC chip is detected with a valid MAC address, all other Simprints scanners are programmatically unpaired and the we pair only to the provided scanner. +Once an NFC chip is detected with a valid MAC address, all other Simprints scanners are programmatically unpaired and the we pair only to +the provided scanner. When pairing, the fragment is listening for `BluetoothDevice.ACTION_BOND_STATE_CHANGED` to detect if the bond was successful. -Even if pairing is successful, this action sometimes never activates (suspected bug in Android on some devices that can be fixed by restarting the device). +Even if pairing is successful, this action sometimes never activates (suspected bug in Android on some devices that can be fixed by +restarting the device). For this reason, there is additionally a timeout to check whether the pairing was successful. The pairing will fail if the device was off. In this case, the user is prompted to turn the device on and try again. @@ -64,33 +78,44 @@ If the user is struggling to detect the NFC chip, there is link to the `SerialEn Upon successful pairing, restarts connecting and returns to the `ConnectScannerMainFragment`. ### SerialEntryPairFragment -This fragment is the fallback to `NfcPairFragment`, and is triggered when the user confirms the wrong scanner is paired, if there are no scanners paired, + +This fragment is the fallback to `NfcPairFragment`, and is triggered when the user confirms the wrong scanner is paired, if there are no +scanners paired, or if there are multiple scanners paired, but in projects using Vero 1 or if the phone does not have an NFC adapter. Can additionally be triggered by the `NfcPairFragment` if the user had difficulty detecting the NFC chip. -The user can enter a serial number as a stand-in for the NFC chip in the `NfcPairFragment`, and the consequent pairing, listening for bond state action, retry, and timeout behaviour is identical. +The user can enter a serial number as a stand-in for the NFC chip in the `NfcPairFragment`, and the consequent pairing, listening for bond +state action, retry, and timeout behaviour is identical. Upon successful pairing, restarts connecting and returns to the `ConnectScannerMainFragment`. ### OtaFragment + If an `OtaAvailableException` is thrown during setup, the `OtaFragment` is shown. This fragment executes the OTA procedure, which updates the firmware of the various chips on the scanner. The progress bar tracks the state of the OTA steps. If multiple chips are being updated, they share a portion of the progress bar. The scanner is assumed to be connected and in Root mode upon entry to this fragment. -If the update is successful for all chips, we return to the `ConnectScannerMainFragment`, where the scanner reconnects and the flow proceeds normally. +If the update is successful for all chips, we return to the `ConnectScannerMainFragment`, where the scanner reconnects and the flow proceeds +normally. -If the update for any of the chips fails, then we go to the `OtaRecoveryFragment` if we still are retrying, otherwise we go to the `OtaFailedFragment` if the final attempt failed. +If the update for any of the chips fails, then we go to the `OtaRecoveryFragment` if we still are retrying, otherwise we go to the +`OtaFailedFragment` if the final attempt failed. ### OtaRecoveryFragment + This fragment is entered from the `OtaFragment` if OTA fails and user action is required to reset the scanner. -Depending on the current step that failed during OTA, a message for either a soft (simple turning off then on) or hard (long press of power button for 5+ seconds) reset is shown. +Depending on the current step that failed during OTA, a message for either a soft (simple turning off then on) or hard (long press of power +button for 5+ seconds) reset is shown. The button attempts a reconnect to the scanner. -If the reconnect succeeds, we go back to the `OtaFragment` to re-attempt the remaining OTA updates needed as well as incrementing the retry attempt counter. +If the reconnect succeeds, we go back to the `OtaFragment` to re-attempt the remaining OTA updates needed as well as incrementing the retry +attempt counter. -If the reconnect fails for whatever reason, we assume the scanner is in an irrecoverable state and take the user to the `OtaFailedFragment`. +If the reconnect fails for whatever reason, we assume the scanner is in an irrecoverable state and take the user to the `OtaFailedFragment`. ### OtaFailedFragment -This fragment only displays a message to the user to contact their supervisor as the scanner may be in an irrecoverable state after a failed OTA update attempt. + +This fragment only displays a message to the user to contact their supervisor as the scanner may be in an irrecoverable state after a failed +OTA update attempt. Pressing Continue will exit the entire fingerprint flow failure result. diff --git a/fingerprint/infra/base-bio-sdk/README.md b/fingerprint/infra/base-bio-sdk/README.md index b72bd6e52e..dde40dc75c 100644 --- a/fingerprint/infra/base-bio-sdk/README.md +++ b/fingerprint/infra/base-bio-sdk/README.md @@ -3,10 +3,8 @@ This is a base fingerprint SDK that provides three operations: init, capture fingerprint images/templates , and match images. to implement this SDK, you need to implement the following interfaces: -```SdkInitializer``` - initialize the SDK using the proper initialization params - -```FingerprintImageProvider and FingerprintTemplateProvider``` - capture fingerprint images/templates - -```FingerprintMatcher``` - match fingerprint templates +`SdkInitializer` - initialize the SDK using the proper initialization params +`FingerprintImageProvider` and `FingerprintTemplateProvider` - capture fingerprint images/templates +`FingerprintMatcher` - match fingerprint templates diff --git a/fingerprint/infra/scanner/README.md b/fingerprint/infra/scanner/README.md index 5932db804c..ea47a5efda 100644 --- a/fingerprint/infra/scanner/README.md +++ b/fingerprint/infra/scanner/README.md @@ -8,6 +8,5 @@ It is split into two subpackages depending on which generation of Vero is being ### Bluetooth Component Abstractions -It's important to use the -[Component abstractions](src/main/java/com/simprints/fingerprint/infra/scanner/component/bluetooth) for connecting via -Bluetooth and acquiring a Bluetooth socket so that mocking and replacing of the Bluetooth adapter can occur easily. +It's important to use the[Component abstractions](src/main/java/com/simprints/fingerprint/infra/scanner/component/bluetooth) for connecting +via Bluetooth and acquiring a Bluetooth socket so that mocking and replacing of the Bluetooth adapter can occur easily. diff --git a/fingerprint/infra/scanner/doc/data_pipeline_diagram.png b/fingerprint/infra/scanner/doc/data_pipeline_diagram.png deleted file mode 100644 index 8c1229d46f..0000000000 Binary files a/fingerprint/infra/scanner/doc/data_pipeline_diagram.png and /dev/null differ diff --git a/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/data/README.md b/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/data/README.md index 789e4e8b3d..97de352187 100644 --- a/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/data/README.md +++ b/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/data/README.md @@ -1,25 +1,13 @@ # Firmware Repository Summary -This sub-package handle the downloading of the firmware binaries from -the cloud: +This sub-package handle the downloading of the firmware binaries from the cloud: -1. Every time the fingerprint `OrchestratorActivity` is called, the - `FirmwareFileUpdateScheduler` schedules the - `FirmwareFileUpdateWorker` -2. `FirmwareFileUpdateWorker` calls `FirmwareRepository` to update the - local firmware files with the latest versions. If this fails for - whatever reason, it is retried with Android’s default exponential - back-off retry policy. -3. `FirmwareRepository` uses `FirmwareLocalDataSource` to check which - current versions are on the phone -4. It then makes a request to the back-end via - `FirmwareRemoteDataSource` to get the URLs of downloadable binaries - if there are any. -5. It then calls `FirmwareRemoteDataSource` to download the binaries - with the URL (which is a short lived URL). -6. It then saves the binaries with `FirmwareLocalDataSource`. Any old - binaries are deleted. -7. With this flow, the phone always has the latest version of each - binary stored. The next time the scanner connects to the phone, if - the version on the scanner is less than the stored version, the OTA - update commences. +1. Every time the fingerprint `OrchestratorActivity` is called, the `FirmwareFileUpdateScheduler` schedules the`FirmwareFileUpdateWorker` +2. `FirmwareFileUpdateWorker` calls `FirmwareRepository` to update the local firmware files with the latest versions. If this fails for + whatever reason, it is retried with Android’s default exponential back-off retry policy. +3. `FirmwareRepository` uses `FirmwareLocalDataSource` to check which current versions are on the phone +4. It then makes a request to the back-end via `FirmwareRemoteDataSource` to get the URLs of downloadable binaries if there are any. +5. It then calls `FirmwareRemoteDataSource` to download the binaries with the URL (which is a short lived URL). +6. It then saves the binaries with `FirmwareLocalDataSource`. Any old binaries are deleted. +7. With this flow, the phone always has the latest version of each binary stored. The next time the scanner connects to the phone, if the + version on the scanner is less than the stored version, the OTA update commences. diff --git a/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/v2/README.md b/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/v2/README.md index 7466464e09..194c0e2d37 100644 --- a/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/v2/README.md +++ b/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/v2/README.md @@ -2,9 +2,11 @@ ## Overview -This package provides an interface for the Vero 2 fingerprint scanner, enabling communication over Bluetooth. The main class, [`Scanner`](scanner/Scanner.kt), serves as the primary entry point for accessing all supported functionalities of the Vero 2. +This package provides an interface for the Vero 2 fingerprint scanner, enabling communication over Bluetooth. The main class, [ +`Scanner`](scanner/Scanner.kt), serves as the primary entry point for accessing all supported functionalities of the Vero 2. -Although written in Kotlin for Android, the package is platform-agnostic, as it has no Android-specific dependencies. It requires only `java.io.InputStream` and `java.io.OutputStream`, which are provided after establishing a Bluetooth socket connection. +Although written in Kotlin for Android, the package is platform-agnostic, as it has no Android-specific dependencies. It requires only +`java.io.InputStream` and `java.io.OutputStream`, which are provided after establishing a Bluetooth socket connection. --- @@ -132,5 +134,6 @@ Vero 2 comprises three chips: --- -This README provides a detailed overview of the Fingerprint Scanner V2 package. For further details, explore the source code and accompanying documentation. +This README provides a detailed overview of the Fingerprint Scanner V2 package. For further details, explore the source code and +accompanying documentation. diff --git a/fingerprint/infra/scannermock/README.md b/fingerprint/infra/scannermock/README.md index fa2d79acee..9961ae9856 100644 --- a/fingerprint/infra/scannermock/README.md +++ b/fingerprint/infra/scannermock/README.md @@ -1,30 +1,45 @@ # Scanner Mock Module README -The Scanner Mock Module provides alternative Bluetooth adapters for replacing real Vero2 or Vero1 scanners in testing environments. This module includes adapters to simulate fingerprint capturing scenarios, record Bluetooth data for debugging, or serve as simple placeholders in basic tests. This README provides guidance on setting up and using each of these mock adapters in your testing environment. +The Scanner Mock Module provides alternative Bluetooth adapters for replacing real Vero2 or Vero1 scanners in testing environments. This +module includes adapters to simulate fingerprint capturing scenarios, record Bluetooth data for debugging, or serve as simple placeholders +in basic tests. This README provides guidance on setting up and using each of these mock adapters in your testing environment. --- ## 1. Replacing the Real Android Bluetooth Adapter To replace the real `AndroidBluetoothAdapter` with one of the mock adapters, select the appropriate adapter for your test case: -- Substitute the real `AndroidBluetoothAdapter` with `SimulatedBluetoothAdapter` in your DI setup. [Example](../../connect/src/main/java/com/simprints/fingerprint/connect/ScannerConnectModule.kt). + +- Substitute the real `AndroidBluetoothAdapter` with `SimulatedBluetoothAdapter` in your DI + setup. [Example](../../connect/src/main/java/com/simprints/fingerprint/connect/ScannerConnectModule.kt). + ### A. **SimulatedBluetoothAdapter** -Use the `SimulatedBluetoothAdapter` to fully simulate the fingerprint capturing scenario in NEC or SimMatcher flows. This adapter is designed to emulate the complete scanning and capturing process, providing success and error responses similar to those from real scanners. +Use the `SimulatedBluetoothAdapter` to fully simulate the fingerprint capturing scenario in NEC or SimMatcher flows. This adapter is +designed to emulate the complete scanning and capturing process, providing success and error responses similar to those from real scanners. #### Setup -- Configure the test data in `SimulatedUn20ResponseHelper` to match your test case needs. This helper currently contains all necessary data for a successful fingerprint collection flow, but you can adjust it for specific scenarios or errors. + +- Configure the test data in `SimulatedUn20ResponseHelper` to match your test case needs. This helper currently contains all necessary data + for a successful fingerprint collection flow, but you can adjust it for specific scenarios or errors. #### Reference -More details on using the `SimulatedBluetoothAdapter` can be found in the [README](../scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/simulated/README.md). + +More details on using the `SimulatedBluetoothAdapter` can be found in +the [README](../scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/simulated/README.md). ### B. **AndroidRecordBluetoothAdapter** -The `AndroidRecordBluetoothAdapter` mimics the real Android Bluetooth components with the added functionality of recording incoming data bytes from the scanner to a file. This is particularly useful for debugging purposes, allowing you to analyze the exact data transmitted during the fingerprint scanning process. -More details on using the `AndroidRecordBluetoothAdapter` can be found in the [README](../scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/record/README.md). +The `AndroidRecordBluetoothAdapter` mimics the real Android Bluetooth components with the added functionality of recording incoming data +bytes from the scanner to a file. This is particularly useful for debugging purposes, allowing you to analyze the exact data transmitted +during the fingerprint scanning process. +More details on using the `AndroidRecordBluetoothAdapter` can be found in +the [README](../scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/record/README.md). + ### C. **DummyBluetoothAdapter** -The `DummyBluetoothAdapter` serves as a simple placeholder adapter, useful in tests that require a Bluetooth component but do not involve actual data transmission or device communication. +The `DummyBluetoothAdapter` serves as a simple placeholder adapter, useful in tests that require a Bluetooth component but do not involve +actual data transmission or device communication. - This adapter is beneficial when: - You need a `ComponentBluetoothAdapter` instance that is enabled. @@ -38,10 +53,10 @@ The `DummyBluetoothAdapter` serves as a simple placeholder adapter, useful in te Each mock adapter provides specific functionality suited to different test requirements: -| Adapter | Purpose | -|----------------------------|-------------------------------------------------------| -| **SimulatedBluetoothAdapter** | Full simulation of the fingerprint capture process | -| **AndroidRecordBluetoothAdapter** | Real Bluetooth functionality with data recording | -| **DummyBluetoothAdapter** | Basic placeholder with minimal Bluetooth properties| +| Adapter | Purpose | +|-----------------------------------|-----------------------------------------------------| +| **SimulatedBluetoothAdapter** | Full simulation of the fingerprint capture process | +| **AndroidRecordBluetoothAdapter** | Real Bluetooth functionality with data recording | +| **DummyBluetoothAdapter** | Basic placeholder with minimal Bluetooth properties | Choose the adapter that best fits your test scenario to effectively mock the scanner behavior and ensure accurate and efficient testing. diff --git a/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/README.md b/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/README.md index 707ad8cb2b..fb5af1067a 100644 --- a/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/README.md +++ b/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/README.md @@ -1,8 +1,5 @@ # Dummy Bluetooth Components -These classes can be used for insertion into tests for very basic use -allowing tests to compile. They can be used to tick the box of having a -`ComponentBluetoothAdapter` that is enabled, or if the MAC address of -the `ComponentBluetoothDevice` is needed. Attempts to connect or -communicate with these devices will throw an -`UnsupportedOperationException`. +These classes can be used for insertion into tests for very basic use allowing tests to compile. They can be used to tick the box of having +a `ComponentBluetoothAdapter` that is enabled, or if the MAC address of the `ComponentBluetoothDevice` is needed. Attempts to connect or +communicate with these devices will throw an `UnsupportedOperationException`. diff --git a/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/dummy/README.md b/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/dummy/README.md index 707ad8cb2b..fb5af1067a 100644 --- a/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/dummy/README.md +++ b/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/dummy/README.md @@ -1,8 +1,5 @@ # Dummy Bluetooth Components -These classes can be used for insertion into tests for very basic use -allowing tests to compile. They can be used to tick the box of having a -`ComponentBluetoothAdapter` that is enabled, or if the MAC address of -the `ComponentBluetoothDevice` is needed. Attempts to connect or -communicate with these devices will throw an -`UnsupportedOperationException`. +These classes can be used for insertion into tests for very basic use allowing tests to compile. They can be used to tick the box of having +a `ComponentBluetoothAdapter` that is enabled, or if the MAC address of the `ComponentBluetoothDevice` is needed. Attempts to connect or +communicate with these devices will throw an `UnsupportedOperationException`. diff --git a/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/record/README.md b/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/record/README.md index c19e7ce936..b17e6d5208 100644 --- a/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/record/README.md +++ b/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/record/README.md @@ -1,6 +1,4 @@ # Recording Bluetooth Adapter -These Bluetooth components are identical to the actual -[Android Bluetooth components](../../../../../../../../fingerprintscanner/src/main/java/com/simprints/fingerprintscanner/component/bluetooth/android/) -with the one difference that incoming bytes from the scanner can be -recorded into a file for debugging purposes. +These Bluetooth components are identical to the actual Android Bluetooth components with the one difference that incoming bytes from the +scanner can be recorded into a file for debugging purposes. diff --git a/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/simulated/README.md b/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/simulated/README.md index 368a2d89c9..b2772570fc 100644 --- a/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/simulated/README.md +++ b/fingerprint/infra/scannermock/src/main/java/com/simprints/fingerprint/infra/scannermock/simulated/README.md @@ -1,9 +1,7 @@ # Simulated Scanner -This package is for simulating the Vero fingerprint scanner for use in -testing, mocking, and debugging. It relies on the -[Component Bluetooth Abstractions](../../../../../../../../fingerprintscanner/src/main/java/com/simprints/fingerprintscanner/component/bluetooth/) -being used in place of Android Bluetooth classes. +This package is for simulating the Vero fingerprint scanner for use in testing, mocking, and debugging. It relies on the Component Bluetooth +Abstractions being used in place of Android Bluetooth classes. It works by reading all bytes that are trying to be sent over Bluetooth, interpreting them, and sending back an appropriate response. It aims to @@ -48,15 +46,15 @@ class SimulatedScannerManager( - `simulationSpeedBehaviour` - How much delay should the simulation add before responding to messages. - `SimulationSpeedBehaviour.INSTANT` will add no delay at all between - receiving a command and returning the response, allowing for very - fast communication. This is ideal for unit and integration tests. - This setting is the default. + receiving a command and returning the response, allowing for very + fast communication. This is ideal for unit and integration tests. + This setting is the default. - `SimulationSpeedBehaviour.REALISTIC` will add a delay between - receiving a command and returning a response depending on the - command, allowing for a realistic feel for the simulated scanner. - Additionally, time will be added between Bluetooth packets. This is - ideal for User-Acceptance Testing or for load-testing the - `fingerprintscanner` module code. + receiving a command and returning a response depending on the + command, allowing for a realistic feel for the simulated scanner. + Additionally, time will be added between Bluetooth packets. This is + ideal for User-Acceptance Testing or for load-testing the + `fingerprintscanner` module code. - `simulatedFingers` - An array of [`SimulatedFinger`s](./common/SimulatedFinger.kt) which are the fingerprints that will be returned by the simulation upon successive @@ -67,12 +65,12 @@ class SimulatedScannerManager( beginning of the array. - The default is `SimulatedFinger.person1TwoFingersGoodScan`. - Multiple versions of the same finger can be used in tests for - successful matching with good match scores during testing, or - different people/fingers can be used for low match scores. + successful matching with good match scores during testing, or + different people/fingers can be used for low match scores. - There are options for good scans and poor scans that yield different - quality scores. + quality scores. - There is an option for if no finger is detected by the scanner at - all, `SimulatedFinger.NO_FINGER`. + all, `SimulatedFinger.NO_FINGER`. - `pairedScannerAddresses` - This is a set of MAC addresses that the will act as if they are paired to the Bluetooth adapter. By default, there is one valid paired MAC address that corresponds to a Vero 1. diff --git a/fingerprint/infra/simafis-wrapper/README.md b/fingerprint/infra/simafis-wrapper/README.md index f7187f7c36..2313ebc76e 100644 --- a/fingerprint/infra/simafis-wrapper/README.md +++ b/fingerprint/infra/simafis-wrapper/README.md @@ -1,4 +1,3 @@ # SIMAfis Matcher Wrapper -This module contains the code used to conduct fingerprint matching. Its -single point of entry to use SIMAfis Matcher +This module contains the code used to conduct fingerprint matching. Its single point of entry to use SIMAfis Matcher diff --git a/id/README.md b/id/README.md deleted file mode 100644 index 88cb9ae0ab..0000000000 --- a/id/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Simprints ID - -This document should be a table of contents for documents inside the [doc](doc) folder, where the documentation for different SimprintsID features can live. - -## TOC - -- [Modularisation document](https://docs.google.com/document/d/1E-SNLGbqsAjn1IVamQhDEcWQJ092tLnNLLeTCo_A160/edit) -- [How the Exit Form flow should work (refusal flow)](/id/doc/exit_form.md) -- [SimprintsID Request/Response](/id/doc/spid_request_response.md) -- [ID Orchestrator Flow](/id/src/main/java/com/simprints/id/orchestrator/README.md) -- [Modalities configuration](/id/doc/modalities_configuration.md) \ No newline at end of file diff --git a/infra/events/src/main/java/com/simprints/infra/events/event/local/README.md b/infra/events/src/main/java/com/simprints/infra/events/event/local/README.md deleted file mode 100644 index 6cfb3561c6..0000000000 --- a/infra/events/src/main/java/com/simprints/infra/events/event/local/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Troubleshooting Room db with events -The events db is room based and encrypted, so to explore the content of the db you need to created a db that is not encrypted: - -* Uninstall SID (if it's installed) -* Go to `EventRoomDatabase.kt` and comment out `.openHelperFactory(factory)` -* Install SID -* Open the Database Inspector in Android studio and go to `dbevents/DbEvent` - -Note: you can't access a db that was already encrypted with a password that was generated by SID diff --git a/infra/logging/README.md b/infra/logging/README.md index 239eeaf08c..8a1a126bb2 100644 --- a/infra/logging/README.md +++ b/infra/logging/README.md @@ -1,13 +1,15 @@ # Logging (a.k.a Simber) -The logging module is a very lightweight wrapper around Timber which has a few goals: -- A very very lightweight wrapper around Jake Wharton’s Timber in case we ever decide to use a different logging tool +The logging module is a very lightweight wrapper in case we ever decide to use a different logging tool + - Clearly document how logging behaves with each build type. -- Isolate the Timber, Firebase Crashlytics and Firebase Analytics dependencies to a single module. This will make it significantly easier for custom versions of SID to remove dependencies on Firebase if they need to. +- Isolate the logging tool, Firebase Crashlytics and Firebase Analytics dependencies to a single module. This will make it significantly + easier for custom versions of SID to remove dependencies on Firebase if they need to. -Access to logging is done solely through the Simber class. See [Simber.kt](src/main/java/com/simprints/logging/Simber.kt) to get started. +Access to logging is done solely through the Simber class. See [Simber.kt](src/main/java/com/simprints/infra/logging/Simber.kt) to get +started. Refs: -See Timber -See Crashlytics -See Firebase Analytics + +* See [Crashlytics](https://firebase.google.com/docs/crashlytics/customize-crash-reports?platform=android) +* See [Firebase Analytics](https://firebase.google.com/docs/analytics/user-properties?platform=android) diff --git a/infra/logging/src/main/java/com/simprints/infra/logging/Simber.kt b/infra/logging/src/main/java/com/simprints/infra/logging/Simber.kt index 0fbe8e4dd2..54da5d2f5c 100644 --- a/infra/logging/src/main/java/com/simprints/infra/logging/Simber.kt +++ b/infra/logging/src/main/java/com/simprints/infra/logging/Simber.kt @@ -9,9 +9,7 @@ import javax.net.ssl.SSLHandshakeException import javax.net.ssl.SSLProtocolException /** - * A very lightweight wrapper around Timber in case we ever decide to use a different logging - * library. - * @see Timber + * A very lightweight wrapper around logging library in case we ever decide to use a different one. */ object Simber { /** diff --git a/infra/ui-base/README.md b/infra/ui-base/README.md index c967cabeeb..99adb4202f 100644 --- a/infra/ui-base/README.md +++ b/infra/ui-base/README.md @@ -4,8 +4,7 @@ This module serves as a common foundation for all modules with any kind on UI. Things that should be stored here: -* Common UI dependencies that are used in all/most feature modules shared via `api()` declaration in - modules build file +* Common UI dependencies that are used in all/most feature modules shared via `api()` declaration in modules build file * Generic utilities that simplify work with UI-related Android API Things that must not be in this module: