@@ -30,22 +30,18 @@ import com.amplifyframework.predictions.PredictionsException
3030import com.amplifyframework.predictions.aws.BuildConfig
3131import com.amplifyframework.predictions.aws.exceptions.AccessDeniedException
3232import com.amplifyframework.predictions.aws.exceptions.FaceLivenessSessionNotFoundException
33- import com.amplifyframework.predictions.aws.exceptions.FaceLivenessUnsupportedChallengeTypeException
3433import com.amplifyframework.predictions.aws.models.liveness.BoundingBox
3534import com.amplifyframework.predictions.aws.models.liveness.ClientChallenge
3635import com.amplifyframework.predictions.aws.models.liveness.ClientSessionInformationEvent
3736import com.amplifyframework.predictions.aws.models.liveness.ColorDisplayed
3837import com.amplifyframework.predictions.aws.models.liveness.FaceMovementAndLightClientChallenge
39- import com.amplifyframework.predictions.aws.models.liveness.FaceMovementClientChallenge
4038import com.amplifyframework.predictions.aws.models.liveness.FreshnessColor
4139import com.amplifyframework.predictions.aws.models.liveness.InitialFace
4240import com.amplifyframework.predictions.aws.models.liveness.InvalidSignatureException
4341import com.amplifyframework.predictions.aws.models.liveness.LivenessResponseStream
4442import com.amplifyframework.predictions.aws.models.liveness.SessionInformation
4543import com.amplifyframework.predictions.aws.models.liveness.TargetFace
4644import com.amplifyframework.predictions.aws.models.liveness.VideoEvent
47- import com.amplifyframework.predictions.models.Challenge
48- import com.amplifyframework.predictions.models.FaceLivenessChallengeType
4945import com.amplifyframework.predictions.models.FaceLivenessSessionInformation
5046import com.amplifyframework.util.UserAgent
5147import java.net.URI
@@ -77,16 +73,12 @@ internal class LivenessWebSocket(
7773 val credentialsProvider : CredentialsProvider ,
7874 val endpoint : String ,
7975 val region : String ,
80- val clientSessionInformation : FaceLivenessSessionInformation ,
76+ val sessionInformation : FaceLivenessSessionInformation ,
8177 val livenessVersion : String? ,
82- val onSessionResponseReceived : Consumer <SessionResponse >,
78+ val onSessionInformationReceived : Consumer <SessionInformation >,
8379 val onErrorReceived : Consumer <PredictionsException >,
8480 val onComplete : Action
8581) {
86- internal data class SessionResponse (
87- val faceLivenessSession : SessionInformation ,
88- val livenessChallengeType : FaceLivenessChallengeType
89- )
9082
9183 private val signer = AWSV4Signer ()
9284 private var credentials: Credentials ? = null
@@ -102,7 +94,6 @@ internal class LivenessWebSocket(
10294 @VisibleForTesting
10395 internal var webSocket: WebSocket ? = null
10496 internal val challengeId = UUID .randomUUID().toString()
105- var challengeType: FaceLivenessChallengeType ? = null
10697 private var initialDetectedFace: BoundingBox ? = null
10798 private var faceDetectedStart = 0L
10899 private var videoStartTimestamp = 0L
@@ -154,34 +145,10 @@ internal class LivenessWebSocket(
154145 try {
155146 when (val response = LivenessEventStream .decode(bytes, json)) {
156147 is LivenessResponseStream .Event -> {
157- if (response.challengeEvent != null ) {
158- challengeType = response.challengeEvent.challengeType
159- } else if (response.serverSessionInformationEvent != null ) {
160-
161- val clientRequestedOldLightChallenge = clientSessionInformation.challengeVersions
162- .any { it == Challenge .FaceMovementAndLightChallenge (" 1.0.0" ) }
163-
164- if (challengeType == null && clientRequestedOldLightChallenge) {
165- // For the 1.0.0 version of FaceMovementAndLight challenge, backend doesn't send a
166- // ChallengeEvent so we need to manually check and set it if that specific challenge
167- // was requested.
168- challengeType = FaceLivenessChallengeType .FaceMovementAndLightChallenge
169- }
170-
171- // If challengeType hasn't been initialized by this point it's because server sent an
172- // unsupported challenge type so return an error to the client and close the web socket.
173- val resolvedChallengeType = challengeType
174- if (resolvedChallengeType == null ) {
175- webSocketError = FaceLivenessUnsupportedChallengeTypeException ()
176- destroy(UNSUPPORTED_CHALLENGE_CLOSURE_STATUS_CODE )
177- } else {
178- onSessionResponseReceived.accept(
179- SessionResponse (
180- response.serverSessionInformationEvent.sessionInformation,
181- resolvedChallengeType
182- )
183- )
184- }
148+ if (response.serverSessionInformationEvent != null ) {
149+ onSessionInformationReceived.accept(
150+ response.serverSessionInformationEvent.sessionInformation
151+ )
185152 } else if (response.disconnectionEvent != null ) {
186153 this @LivenessWebSocket.webSocket?.close(
187154 NORMAL_SOCKET_CLOSURE_STATUS_CODE ,
@@ -391,26 +358,16 @@ internal class LivenessWebSocket(
391358 // Send initial ClientSessionInformationEvent
392359 videoStartTimestamp = adjustedDate(videoStartTime)
393360 initialDetectedFace = BoundingBox (
394- left = initialFaceRect.left / clientSessionInformation .videoWidth,
395- top = initialFaceRect.top / clientSessionInformation .videoHeight,
396- height = initialFaceRect.height() / clientSessionInformation .videoHeight,
397- width = initialFaceRect.width() / clientSessionInformation .videoWidth
361+ left = initialFaceRect.left / sessionInformation .videoWidth,
362+ top = initialFaceRect.top / sessionInformation .videoHeight,
363+ height = initialFaceRect.height() / sessionInformation .videoHeight,
364+ width = initialFaceRect.width() / sessionInformation .videoWidth
398365 )
399366 faceDetectedStart = adjustedDate(videoStartTime)
400-
401- val resolvedChallengeType = challengeType
402- if (resolvedChallengeType == null ) {
403- onErrorReceived.accept(
404- PredictionsException (
405- " Failed to send an initial face detected event" ,
406- AmplifyException .TODO_RECOVERY_SUGGESTION
407- )
408- )
409- } else {
410- val clientInfoEvent =
411- ClientSessionInformationEvent (
412- challenge = buildClientChallenge(
413- challengeType = resolvedChallengeType,
367+ val clientInfoEvent =
368+ ClientSessionInformationEvent (
369+ challenge = ClientChallenge (
370+ faceMovementAndLightChallenge = FaceMovementAndLightClientChallenge (
414371 challengeId = challengeId,
415372 initialFace = InitialFace (
416373 boundingBox = initialDetectedFace!! ,
@@ -419,23 +376,14 @@ internal class LivenessWebSocket(
419376 videoStartTimestamp = videoStartTimestamp
420377 )
421378 )
422- sendClientInfoEvent(clientInfoEvent )
423- }
379+ )
380+ sendClientInfoEvent(clientInfoEvent)
424381 }
425382
426383 fun sendFinalEvent (targetFaceRect : RectF , faceMatchedStart : Long , faceMatchedEnd : Long ) {
427- val resolvedChallengeType = challengeType
428- if (resolvedChallengeType == null ) {
429- onErrorReceived.accept(
430- PredictionsException (
431- " Failed to send an initial face detected event" ,
432- AmplifyException .TODO_RECOVERY_SUGGESTION
433- )
434- )
435- } else {
436- val finalClientInfoEvent = ClientSessionInformationEvent (
437- challenge = buildClientChallenge(
438- challengeType = resolvedChallengeType,
384+ val finalClientInfoEvent = ClientSessionInformationEvent (
385+ challenge = ClientChallenge (
386+ FaceMovementAndLightClientChallenge (
439387 challengeId = challengeId,
440388 videoEndTimestamp = videoEndTimestamp,
441389 initialFace = InitialFace (
@@ -446,16 +394,16 @@ internal class LivenessWebSocket(
446394 faceDetectedInTargetPositionStartTimestamp = adjustedDate(faceMatchedStart),
447395 faceDetectedInTargetPositionEndTimestamp = adjustedDate(faceMatchedEnd),
448396 boundingBox = BoundingBox (
449- left = targetFaceRect.left / clientSessionInformation .videoWidth,
450- top = targetFaceRect.top / clientSessionInformation .videoHeight,
451- height = targetFaceRect.height() / clientSessionInformation .videoHeight,
452- width = targetFaceRect.width() / clientSessionInformation .videoWidth
397+ left = targetFaceRect.left / sessionInformation .videoWidth,
398+ top = targetFaceRect.top / sessionInformation .videoHeight,
399+ height = targetFaceRect.height() / sessionInformation .videoHeight,
400+ width = targetFaceRect.width() / sessionInformation .videoWidth
453401 )
454402 )
455403 )
456404 )
457- sendClientInfoEvent(finalClientInfoEvent )
458- }
405+ )
406+ sendClientInfoEvent(finalClientInfoEvent)
459407 }
460408
461409 fun sendColorDisplayedEvent (
@@ -575,46 +523,8 @@ internal class LivenessWebSocket(
575523
576524 private fun isTimeDiffSafe (diffInMillis : Long ) = kotlin.math.abs(diffInMillis) < FOUR_MINUTES
577525
578- private fun buildClientChallenge (
579- challengeType : FaceLivenessChallengeType ,
580- challengeId : String ,
581- videoStartTimestamp : Long? = null,
582- videoEndTimestamp : Long? = null,
583- initialFace : InitialFace ? = null,
584- targetFace : TargetFace ? = null,
585- colorDisplayed : ColorDisplayed ? = null
586- ): ClientChallenge = when (challengeType) {
587- FaceLivenessChallengeType .FaceMovementAndLightChallenge -> {
588- ClientChallenge (
589- faceMovementAndLightChallenge = FaceMovementAndLightClientChallenge (
590- challengeId = challengeId,
591- videoStartTimestamp = videoStartTimestamp,
592- videoEndTimestamp = videoEndTimestamp,
593- initialFace = initialFace,
594- targetFace = targetFace,
595- colorDisplayed = colorDisplayed
596- ),
597- faceMovementChallenge = null
598- )
599- }
600- FaceLivenessChallengeType .FaceMovementChallenge -> {
601- ClientChallenge (
602- faceMovementAndLightChallenge = null ,
603- faceMovementChallenge = FaceMovementClientChallenge (
604- challengeId = challengeId,
605- videoStartTimestamp = videoStartTimestamp,
606- videoEndTimestamp = videoEndTimestamp,
607- initialFace = initialFace,
608- targetFace = targetFace
609- )
610- )
611- }
612- }
613-
614526 companion object {
615527 private const val NORMAL_SOCKET_CLOSURE_STATUS_CODE = 1000
616- // This is the same as the client-provided 'runtime error' status code
617- private const val UNSUPPORTED_CHALLENGE_CLOSURE_STATUS_CODE = 4005
618528 private const val FOUR_MINUTES = 1000 * 60 * 4
619529 @VisibleForTesting val datePattern = " EEE, d MMM yyyy HH:mm:ss z"
620530 private val LOG = Amplify .Logging .logger(CategoryType .PREDICTIONS , " amplify:aws-predictions" )
0 commit comments