@@ -27,6 +27,7 @@ import androidx.compose.foundation.layout.padding
27
27
import androidx.compose.foundation.layout.size
28
28
import androidx.compose.foundation.layout.width
29
29
import androidx.compose.material3.Button
30
+ import androidx.compose.material3.CircularProgressIndicator
30
31
import androidx.compose.material3.LinearProgressIndicator
31
32
import androidx.compose.material3.MaterialTheme
32
33
import androidx.compose.material3.Surface
@@ -72,6 +73,7 @@ import kotlinx.coroutines.launch
72
73
* @param region AWS region to stream the video to. Current supported regions are listed in [add link here]
73
74
* @param credentialsProvider to provide custom CredentialsProvider for authentication. Default uses initialized Amplify.Auth CredentialsProvider
74
75
* @param disableStartView to bypass warmup screen.
76
+ * @param challengeOptions is the list of ChallengeOptions that are to be overridden from the default configuration
75
77
* @param onComplete callback notifying a completed challenge
76
78
* @param onError callback containing exception for cause
77
79
*/
@@ -81,6 +83,7 @@ fun FaceLivenessDetector(
81
83
region : String ,
82
84
credentialsProvider : AWSCredentialsProvider <AWSCredentials >? = null,
83
85
disableStartView : Boolean = false,
86
+ challengeOptions : ChallengeOptions = ChallengeOptions (),
84
87
onComplete : Action ,
85
88
onError : Consumer <FaceLivenessDetectionException >
86
89
) {
@@ -124,6 +127,7 @@ fun FaceLivenessDetector(
124
127
region,
125
128
credentialsProvider = credentialsProvider,
126
129
disableStartView,
130
+ challengeOptions = challengeOptions,
127
131
onChallengeComplete = {
128
132
scope.launch {
129
133
// if we are already finished, we already provided a result in complete or failed
@@ -156,6 +160,7 @@ internal fun ChallengeView(
156
160
region : String ,
157
161
credentialsProvider : AWSCredentialsProvider <AWSCredentials >? ,
158
162
disableStartView : Boolean ,
163
+ challengeOptions : ChallengeOptions ,
159
164
onChallengeComplete : OnChallengeComplete ,
160
165
onChallengeFailed : Consumer <FaceLivenessDetectionException >
161
166
) {
@@ -176,6 +181,7 @@ internal fun ChallengeView(
176
181
region,
177
182
credentialsProvider,
178
183
disableStartView,
184
+ challengeOptions,
179
185
onChallengeComplete = { currentOnChallengeComplete() },
180
186
onChallengeFailed = { currentOnChallengeFailed.accept(it) }
181
187
)
@@ -232,6 +238,15 @@ internal fun ChallengeView(
232
238
233
239
if (livenessState.showingStartView) {
234
240
241
+ if (livenessState.loadingCameraPreview) {
242
+ CircularProgressIndicator (
243
+ color = MaterialTheme .colorScheme.primary,
244
+ modifier = Modifier
245
+ .align(Alignment .Center ),
246
+ strokeWidth = 2 .dp,
247
+ )
248
+ }
249
+
235
250
FaceGuide (
236
251
modifier = Modifier
237
252
.fillMaxSize()
@@ -402,6 +417,40 @@ internal fun ChallengeView(
402
417
}
403
418
}
404
419
420
+ data class ChallengeOptions (
421
+ val faceMovementAndLight : LivenessChallenge .FaceMovementAndLight = LivenessChallenge .FaceMovementAndLight ,
422
+ val faceMovement : LivenessChallenge .FaceMovement = LivenessChallenge .FaceMovement ()
423
+ ) {
424
+ fun getOptions (challengeType : FaceLivenessChallengeType ): LivenessChallenge =
425
+ when (challengeType) {
426
+ FaceLivenessChallengeType .FaceMovementAndLightChallenge -> faceMovementAndLight
427
+ FaceLivenessChallengeType .FaceMovementChallenge -> faceMovement
428
+ }
429
+
430
+ /* *
431
+ * @return true if all of the challenge options are configured to use the same camera configuration
432
+ */
433
+ fun hasOneCameraConfigured (): Boolean =
434
+ listOf (
435
+ faceMovementAndLight,
436
+ faceMovement
437
+ ).all { it.camera == faceMovementAndLight.camera }
438
+ }
439
+
440
+ sealed class LivenessChallenge (
441
+ val camera : Camera = Camera .Front
442
+ ) {
443
+ class FaceMovement (camera : Camera = Camera .Front ): LivenessChallenge(
444
+ camera = camera
445
+ )
446
+ object FaceMovementAndLight: LivenessChallenge()
447
+ }
448
+
449
+ sealed class Camera {
450
+ object Front: Camera()
451
+ object Back: Camera()
452
+ }
453
+
405
454
private fun FaceLivenessSession?.isFaceMovementAndLightChallenge (): Boolean =
406
455
this ?.challengeType == FaceLivenessChallengeType .FaceMovementAndLightChallenge
407
456
0 commit comments