Skip to content

Commit

Permalink
Revert "feat(predictions): Add support for a no light freshness chall…
Browse files Browse the repository at this point in the history
…enge" (#2868)
  • Loading branch information
vincetran authored Jul 2, 2024
1 parent f37e5b0 commit 6bbb8c4
Show file tree
Hide file tree
Showing 14 changed files with 93 additions and 839 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,18 @@ import com.amplifyframework.predictions.PredictionsException
import com.amplifyframework.predictions.aws.BuildConfig
import com.amplifyframework.predictions.aws.exceptions.AccessDeniedException
import com.amplifyframework.predictions.aws.exceptions.FaceLivenessSessionNotFoundException
import com.amplifyframework.predictions.aws.exceptions.FaceLivenessUnsupportedChallengeTypeException
import com.amplifyframework.predictions.aws.models.liveness.BoundingBox
import com.amplifyframework.predictions.aws.models.liveness.ClientChallenge
import com.amplifyframework.predictions.aws.models.liveness.ClientSessionInformationEvent
import com.amplifyframework.predictions.aws.models.liveness.ColorDisplayed
import com.amplifyframework.predictions.aws.models.liveness.FaceMovementAndLightClientChallenge
import com.amplifyframework.predictions.aws.models.liveness.FaceMovementClientChallenge
import com.amplifyframework.predictions.aws.models.liveness.FreshnessColor
import com.amplifyframework.predictions.aws.models.liveness.InitialFace
import com.amplifyframework.predictions.aws.models.liveness.InvalidSignatureException
import com.amplifyframework.predictions.aws.models.liveness.LivenessResponseStream
import com.amplifyframework.predictions.aws.models.liveness.SessionInformation
import com.amplifyframework.predictions.aws.models.liveness.TargetFace
import com.amplifyframework.predictions.aws.models.liveness.VideoEvent
import com.amplifyframework.predictions.models.Challenge
import com.amplifyframework.predictions.models.FaceLivenessChallengeType
import com.amplifyframework.predictions.models.FaceLivenessSessionInformation
import com.amplifyframework.util.UserAgent
import java.net.URI
Expand Down Expand Up @@ -77,16 +73,12 @@ internal class LivenessWebSocket(
val credentialsProvider: CredentialsProvider,
val endpoint: String,
val region: String,
val clientSessionInformation: FaceLivenessSessionInformation,
val sessionInformation: FaceLivenessSessionInformation,
val livenessVersion: String?,
val onSessionResponseReceived: Consumer<SessionResponse>,
val onSessionInformationReceived: Consumer<SessionInformation>,
val onErrorReceived: Consumer<PredictionsException>,
val onComplete: Action
) {
internal data class SessionResponse(
val faceLivenessSession: SessionInformation,
val livenessChallengeType: FaceLivenessChallengeType
)

private val signer = AWSV4Signer()
private var credentials: Credentials? = null
Expand All @@ -102,7 +94,6 @@ internal class LivenessWebSocket(
@VisibleForTesting
internal var webSocket: WebSocket? = null
internal val challengeId = UUID.randomUUID().toString()
var challengeType: FaceLivenessChallengeType? = null
private var initialDetectedFace: BoundingBox? = null
private var faceDetectedStart = 0L
private var videoStartTimestamp = 0L
Expand Down Expand Up @@ -154,34 +145,10 @@ internal class LivenessWebSocket(
try {
when (val response = LivenessEventStream.decode(bytes, json)) {
is LivenessResponseStream.Event -> {
if (response.challengeEvent != null) {
challengeType = response.challengeEvent.challengeType
} else if (response.serverSessionInformationEvent != null) {

val clientRequestedOldLightChallenge = clientSessionInformation.challengeVersions
.any { it == Challenge.FaceMovementAndLightChallenge("1.0.0") }

if (challengeType == null && clientRequestedOldLightChallenge) {
// For the 1.0.0 version of FaceMovementAndLight challenge, backend doesn't send a
// ChallengeEvent so we need to manually check and set it if that specific challenge
// was requested.
challengeType = FaceLivenessChallengeType.FaceMovementAndLightChallenge
}

// If challengeType hasn't been initialized by this point it's because server sent an
// unsupported challenge type so return an error to the client and close the web socket.
val resolvedChallengeType = challengeType
if (resolvedChallengeType == null) {
webSocketError = FaceLivenessUnsupportedChallengeTypeException()
destroy(UNSUPPORTED_CHALLENGE_CLOSURE_STATUS_CODE)
} else {
onSessionResponseReceived.accept(
SessionResponse(
response.serverSessionInformationEvent.sessionInformation,
resolvedChallengeType
)
)
}
if (response.serverSessionInformationEvent != null) {
onSessionInformationReceived.accept(
response.serverSessionInformationEvent.sessionInformation
)
} else if (response.disconnectionEvent != null) {
this@LivenessWebSocket.webSocket?.close(
NORMAL_SOCKET_CLOSURE_STATUS_CODE,
Expand Down Expand Up @@ -391,26 +358,16 @@ internal class LivenessWebSocket(
// Send initial ClientSessionInformationEvent
videoStartTimestamp = adjustedDate(videoStartTime)
initialDetectedFace = BoundingBox(
left = initialFaceRect.left / clientSessionInformation.videoWidth,
top = initialFaceRect.top / clientSessionInformation.videoHeight,
height = initialFaceRect.height() / clientSessionInformation.videoHeight,
width = initialFaceRect.width() / clientSessionInformation.videoWidth
left = initialFaceRect.left / sessionInformation.videoWidth,
top = initialFaceRect.top / sessionInformation.videoHeight,
height = initialFaceRect.height() / sessionInformation.videoHeight,
width = initialFaceRect.width() / sessionInformation.videoWidth
)
faceDetectedStart = adjustedDate(videoStartTime)

val resolvedChallengeType = challengeType
if (resolvedChallengeType == null) {
onErrorReceived.accept(
PredictionsException(
"Failed to send an initial face detected event",
AmplifyException.TODO_RECOVERY_SUGGESTION
)
)
} else {
val clientInfoEvent =
ClientSessionInformationEvent(
challenge = buildClientChallenge(
challengeType = resolvedChallengeType,
val clientInfoEvent =
ClientSessionInformationEvent(
challenge = ClientChallenge(
faceMovementAndLightChallenge = FaceMovementAndLightClientChallenge(
challengeId = challengeId,
initialFace = InitialFace(
boundingBox = initialDetectedFace!!,
Expand All @@ -419,23 +376,14 @@ internal class LivenessWebSocket(
videoStartTimestamp = videoStartTimestamp
)
)
sendClientInfoEvent(clientInfoEvent)
}
)
sendClientInfoEvent(clientInfoEvent)
}

fun sendFinalEvent(targetFaceRect: RectF, faceMatchedStart: Long, faceMatchedEnd: Long) {
val resolvedChallengeType = challengeType
if (resolvedChallengeType == null) {
onErrorReceived.accept(
PredictionsException(
"Failed to send an initial face detected event",
AmplifyException.TODO_RECOVERY_SUGGESTION
)
)
} else {
val finalClientInfoEvent = ClientSessionInformationEvent(
challenge = buildClientChallenge(
challengeType = resolvedChallengeType,
val finalClientInfoEvent = ClientSessionInformationEvent(
challenge = ClientChallenge(
FaceMovementAndLightClientChallenge(
challengeId = challengeId,
videoEndTimestamp = videoEndTimestamp,
initialFace = InitialFace(
Expand All @@ -446,16 +394,16 @@ internal class LivenessWebSocket(
faceDetectedInTargetPositionStartTimestamp = adjustedDate(faceMatchedStart),
faceDetectedInTargetPositionEndTimestamp = adjustedDate(faceMatchedEnd),
boundingBox = BoundingBox(
left = targetFaceRect.left / clientSessionInformation.videoWidth,
top = targetFaceRect.top / clientSessionInformation.videoHeight,
height = targetFaceRect.height() / clientSessionInformation.videoHeight,
width = targetFaceRect.width() / clientSessionInformation.videoWidth
left = targetFaceRect.left / sessionInformation.videoWidth,
top = targetFaceRect.top / sessionInformation.videoHeight,
height = targetFaceRect.height() / sessionInformation.videoHeight,
width = targetFaceRect.width() / sessionInformation.videoWidth
)
)
)
)
sendClientInfoEvent(finalClientInfoEvent)
}
)
sendClientInfoEvent(finalClientInfoEvent)
}

fun sendColorDisplayedEvent(
Expand Down Expand Up @@ -575,46 +523,8 @@ internal class LivenessWebSocket(

private fun isTimeDiffSafe(diffInMillis: Long) = kotlin.math.abs(diffInMillis) < FOUR_MINUTES

private fun buildClientChallenge(
challengeType: FaceLivenessChallengeType,
challengeId: String,
videoStartTimestamp: Long? = null,
videoEndTimestamp: Long? = null,
initialFace: InitialFace? = null,
targetFace: TargetFace? = null,
colorDisplayed: ColorDisplayed? = null
): ClientChallenge = when (challengeType) {
FaceLivenessChallengeType.FaceMovementAndLightChallenge -> {
ClientChallenge(
faceMovementAndLightChallenge = FaceMovementAndLightClientChallenge(
challengeId = challengeId,
videoStartTimestamp = videoStartTimestamp,
videoEndTimestamp = videoEndTimestamp,
initialFace = initialFace,
targetFace = targetFace,
colorDisplayed = colorDisplayed
),
faceMovementChallenge = null
)
}
FaceLivenessChallengeType.FaceMovementChallenge -> {
ClientChallenge(
faceMovementAndLightChallenge = null,
faceMovementChallenge = FaceMovementClientChallenge(
challengeId = challengeId,
videoStartTimestamp = videoStartTimestamp,
videoEndTimestamp = videoEndTimestamp,
initialFace = initialFace,
targetFace = targetFace
)
)
}
}

companion object {
private const val NORMAL_SOCKET_CLOSURE_STATUS_CODE = 1000
// This is the same as the client-provided 'runtime error' status code
private const val UNSUPPORTED_CHALLENGE_CLOSURE_STATUS_CODE = 4005
private const val FOUR_MINUTES = 1000 * 60 * 4
@VisibleForTesting val datePattern = "EEE, d MMM yyyy HH:mm:ss z"
private val LOG = Amplify.Logging.logger(CategoryType.PREDICTIONS, "amplify:aws-predictions")
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,5 @@ import kotlinx.serialization.Serializable

@Serializable
internal data class ClientChallenge(
@SerialName("FaceMovementAndLightChallenge") val faceMovementAndLightChallenge:
FaceMovementAndLightClientChallenge? = null,
@SerialName("FaceMovementChallenge") val faceMovementChallenge: FaceMovementClientChallenge? = null
@SerialName("FaceMovementAndLightChallenge") val faceMovementAndLightChallenge: FaceMovementAndLightClientChallenge
)

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ internal sealed class LivenessResponseStream {
internal data class Event(
@SerialName("ServerSessionInformationEvent") val serverSessionInformationEvent:
ServerSessionInformationEvent? = null,
@SerialName("DisconnectionEvent") val disconnectionEvent: DisconnectionEvent? = null,
@SerialName("ChallengeEvent") val challengeEvent: ChallengeEvent? = null
@SerialName("DisconnectionEvent") val disconnectionEvent: DisconnectionEvent? = null
) : LivenessResponseStream()

@Serializable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,5 @@ import kotlinx.serialization.Serializable

@Serializable
internal data class ServerChallenge(
@SerialName("FaceMovementAndLightChallenge") val faceMovementAndLightChallenge:
FaceMovementAndLightServerChallenge? = null,
@SerialName("FaceMovementChallenge") val faceMovementChallenge: FaceMovementServerChallenge? = null
@SerialName("FaceMovementAndLightChallenge") val faceMovementAndLightChallenge: FaceMovementAndLightServerChallenge
)
Loading

0 comments on commit 6bbb8c4

Please sign in to comment.