Enabling Advanced Injection Attack Detection¶
Overview¶
Face Capture provides two workflow options for advanced injection attack detection:
LIGHT_TRACE_STRICT_MODE_OPTIMIZATIONS— Strict Mode Optimizations.SPECTRAL_ANALYSIS— Spectral Analysis.
Both options add more advanced injection attack detection to your workflow. Neither is enabled by default, because both introduce additional considerations for end user applications:
Enabling either option requires additional time to process data after the subject’s photo is taken. To ensure a smooth end user experience, a
POST_CAPTURE_PROCESSINGstatus will be provided. While this is occurring, it is advised to update the UI display, as the SDK will no longer be displaying the camera feed.
The two options differ in which workflows they support, and in some usage advice:
Strict Mode Optimizations is intended for the Charlie workflow only. It is also recommended to advise users to avoid taking pictures outside in direct sunlight, as direct sunlight may increase errors for live users.
Spectral Analysis is supported on both the Charlie and Foxtrot workflows.
Because both options surface the same POST_CAPTURE_PROCESSING behavior, they share a
single post-capture handling implementation. This guide describes how to enable each
option and how to handle the extra processing time on the UI by displaying an animation
during the POST_CAPTURE_PROCESSING phase.
Enabling Strict Mode Optimizations¶
Before starting the Face Capture process, set the LIGHT_TRACE_STRICT_MODE_OPTIMIZATIONS
workflow property to true. The default value is false.
workflow?.setPropertyBool(
WorkflowProperty.LIGHT_TRACE_STRICT_MODE_OPTIMIZATIONS,
true
)
Note
Strict Mode Optimizations is intended for the Charlie workflow only.
When LIGHT_TRACE_STRICT_MODE_OPTIMIZATIONS is enabled, expect an additional
~1 second delay on the CaptureSessionStatus.POST_CAPTURE_PROCESSING callback
before the status transitions to COMPLETED. To improve the user experience
during this delay, it is recommended to display an animation (e.g. a progress
indicator followed by a checkmark). See
Handling Post-Capture Processing.
Enabling Spectral Analysis¶
Before starting the Face Capture process, set the SPECTRAL_ANALYSIS workflow property
to true. The default value is false.
workflow?.setPropertyBool(
WorkflowProperty.SPECTRAL_ANALYSIS,
true
)
Note
Spectral Analysis is supported on both the Charlie and Foxtrot workflows.
When SPECTRAL_ANALYSIS is enabled, expect additional processing time on the
CaptureSessionStatus.POST_CAPTURE_PROCESSING callback before the status
transitions to COMPLETED. To improve the user experience during this delay, it
is recommended to display an animation (e.g. a progress indicator followed by a
checkmark). See
Handling Post-Capture Processing.
Handling Post-Capture Processing¶
Both options above use the same post-capture handling. Regardless of which option you
enabled, the POST_CAPTURE_PROCESSING status is handled identically, so the
implementation below applies to both.
The flow is:
While the status is
POST_CAPTURE_PROCESSING— show a progress animation.When the status becomes
COMPLETED— hide the progress and play a checkmark animation; finalize the capture when the animation ends.
Drawable Resources¶
res/drawable/ic_check.xml¶
The static checkmark vector.
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="96dp"
android:height="96dp"
android:viewportWidth="96"
android:viewportHeight="96">
<path
android:name="check"
android:pathData="M28,50 L42,64 L70,32"
android:fillColor="@android:color/transparent"
android:strokeColor="@color/colorGreen"
android:strokeWidth="6"
android:strokeLineCap="round"
android:strokeLineJoin="round"
android:trimPathEnd="0" />
</vector>
res/animator/check_animator.xml¶
Animates trimPathEnd so the check is drawn stroke-by-stroke.
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="trimPathEnd"
android:duration="1000"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" />
res/drawable/animated_check.xml¶
Binds the animator to the check path inside the vector.
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_check">
<target
android:name="check"
android:animation="@animator/check_animator" />
</animated-vector>
Layout¶
Place a progress indicator and an ImageView for the checkmark inside your capture layout:
<ProgressBar
android:id="@+id/postProcessingProgress"
android:layout_width="64dp"
android:layout_height="64dp"
android:visibility="gone" />
<ImageView
android:id="@+id/imgCheckmark"
android:layout_width="96dp"
android:layout_height="96dp"
android:visibility="gone" />
Activity Logic¶
Inside your capture activity, react to the polling status callbacks.
While in POST_CAPTURE_PROCESSING, show the progress; on COMPLETED, play the checkmark animation and only finalize when it ends.
private var isPostProcessingVisible = false
private var isCompletedHandled = false
override fun onPollingStatusListener(
status: CaptureSessionStatus,
frame: ByteArray?,
feedback: AutoCaptureFeedback?
) {
when (status) {
CaptureSessionStatus.CAPTURING -> processCurrentData(frame, feedback)
CaptureSessionStatus.POST_CAPTURE_PROCESSING -> showPostProcessing()
CaptureSessionStatus.COMPLETED -> playCheckmarkThenEnd()
else -> Unit
}
}
private fun showPostProcessing() {
if (isCompletedHandled || isPostProcessingVisible) return
isPostProcessingVisible = true
binding.imgCheckmark.isVisible = false
binding.postProcessingProgress.isVisible = true
}
private fun playCheckmarkThenEnd() {
if (isCompletedHandled) return
isCompletedHandled = true
isPostProcessingVisible = false
runOnUiThread {
binding.postProcessingProgress.isVisible = false
binding.imgCheckmark.isVisible = true
}
val checkDrawable = AnimatedVectorDrawableCompat.create(
binding.root.context,
R.drawable.animated_check
)
if (checkDrawable == null) {
onCaptureEnd()
return
}
runOnUiThread {
binding.imgCheckmark.setImageDrawable(checkDrawable)
checkDrawable.registerAnimationCallback(object : Animatable2Compat.AnimationCallback() {
override fun onAnimationEnd(drawable: Drawable?) {
binding.imgCheckmark.post {
checkDrawable.clearAnimationCallbacks()
onCaptureEnd()
}
}
})
checkDrawable.start()
}
}
Required Imports¶
import androidx.core.view.isVisible
import androidx.vectordrawable.graphics.drawable.Animatable2Compat
import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
Guard Flags¶
Two flags prevent double-handling of status callbacks, which can arrive multiple times:
isPostProcessingVisible— ensures the progress UI is only shown once per session.isCompletedHandled— ensures the completion animation andonCaptureEnd()run only once, even ifCOMPLETEDis delivered repeatedly.