DOT Android Face 9.0.0

This guide describes how to migrate DOT Android Face version 8.x to version 9.0. Only the most important changes are highlighted in this guide. For more details, see the Android Samples.

Migration Steps

Compatibility with DIS

When utilizing DIS for server-side evaluation, ensure compatibility between your DIS version and the corresponding SDK version. Refer to the DIS vs SDKs compatibility table for detailed compatibility information.

SDK initialization

The way DOT SDK libraries are configured has changed.

  • Replace DotSdkConfiguration with DotSdk.Configuration class.
  • Update libraries property of DotSdk.Configuration class.
  • Update the modules property of the DotFaceLibraryConfiguration class. Instead of a list of modules, it now accepts DotFaceLibraryConfiguration.Modules, which provides an explicit configuration property for each face module.

Before

Libraries were provided as a list of DotLibrary instances and face modules were provided as list of DotFaceModule.

DotSdkConfiguration(
    //...
    libraries = listOf(
        DotFaceLibrary(
            configuration = DotFaceLibraryConfiguration(
                modules = listOf(
                    DotFaceDetectionFastModule(),
                    DotFaceExpressionNeutralModule(),
                    DotFaceEyeGazeLivenessModule(),
                    DotFacePassiveLivenessModule(),
                    DotFaceVerificationModule(),
                ),
                faceDetectionConfidenceThreshold = 0.06,
            )
        ),
        //...
    ),
)

After

Libraries are now configured via a single Libraries object, with explicit configuration for each DOT SDK library. Face modules are configured via DotFaceLibraryConfiguration.Modules, which provides an explicit configuration property for each module instead of a list. Specifying a module configuration activates the module. If a module is not specified or is set to null, it will not be activated.

DotSdk.Configuration(
    //...
    libraries = Libraries(
        face = DotFaceLibraryConfiguration(
            modules = DotFaceLibraryConfiguration.Modules(
                detection = DotFaceDetectionModuleConfiguration.Fast,
                expressionNeutral = DotFaceExpressionNeutralModuleConfiguration,
                eyeGazeLiveness = DotFaceEyeGazeLivenessModuleConfiguration,
                passiveLiveness = DotFacePassiveLivenessModuleConfiguration,
                verification = DotFaceVerificationModuleConfiguration,
            ),
            faceDetectionConfidenceThreshold = 0.06,
        ),
        //...
    ),
)

UI Face Auto Capture component

The FaceAutoCaptureFragment class was moved to a new package, and both its API and configuration structure have changed. Existing configuration objects are not compatible with the new API and must be migrated to the new configuration model. Basic migration steps:

  • Replace import com.innovatrics.dot.face.autocapture.FaceAutoCaptureFragment with import com.innovatrics.dot.face.autocapture.ui.FaceAutoCaptureFragment.
  • Replace the method stopAsync(...) with the new method stop().
  • Remove the override of the onProcessed() method and override onUiStateUpdated(uiState: UiState) instead. UiState is a sealed interface, and its implementation UiState.Running replaces the data previously delivered via onProcessed() method.
  • Update configuration provided by provideConfiguration() method.
  • Replace onCaptured() method with onFinished() method.

Before

//...
import com.innovatrics.dot.face.autocapture.FaceAutoCaptureFragment
//...

class BasicFaceAutoCaptureFragment: FaceAutoCaptureFragment {

    override fun provideConfiguration(): Configuration {
        return Configuration(
            cameraFacing = CameraFacing.FRONT,
            cameraPreviewScaleType = CameraPreviewScaleType.FILL,
            isTorchEnabled = false,
            isVideoCaptureEnabled = false,
            faceSizeRatioInterval = IntervalDouble(0.1, 0.3),
            captureMode = CaptureMode.AUTO_CAPTURE,
            qualityAttributeThresholds = QualityAttributeThresholdPresets.standard,
            minValidFramesInRowToStartCandidateSelection = 2,
            candidateSelectionDurationMillis = 2000,
            isPlaceholderVisible = true,
            isDetectionLayerVisible = false,
            query = FaceDetectionQuery(),
            sessionToken = "...",
            isCameraPreviewVisible = true,
        )
    }

    override fun onProcessed(detection: FaceAutoCaptureDetection) {
        //...
    }

    override fun onCaptured(result: FaceAutoCaptureResult) {
        //...
    }
}

After

//...
import com.innovatrics.dot.face.autocapture.ui.FaceAutoCaptureFragment
//...

class BasicFaceAutoCaptureFragment: FaceAutoCaptureFragment {
  
    override fun provideConfiguration(): Configuration {
        return Configuration(
            base = BaseFaceAutoCaptureFragment.Configuration(
                common = CommonConfiguration(
                    sessionToken = "..."
                ),
                camera = CameraConfiguration(
                    facing = CameraFacing.FRONT,
                    previewScaleType = CameraPreviewScaleType.FIT,
                    isTorchEnabled = false,
                    isVideoCaptureEnabled = false,
                    isPreviewVisible = false,
                ),
                autoCapture = AutoCaptureConfiguration(
                    minValidSamplesInRowToStartCandidateSelection = 2,
                    candidateSelectionDurationMillis = 2000,
                ),
                faceLibraryComponent = FaceLibraryComponentConfiguration(
                    faceSizeRatioInterval = IntervalDouble(0.1, 0.3),
                    query = FaceDetectionQuery(),
                ),
                qualityAttributeThresholds = QualityAttributeThresholds.Presets.standard,
                captureMode = CaptureMode.AUTO_CAPTURE,
            ),
            placeholder = Placeholder.Visible(
                type = Placeholder.Visible.Type.CIRCLE,
            ),
            isDetectionLayerVisible = false,
        )
    }

    override fun onUiStateUpdated(uiState: UiState) {
        if (uiState is UiState.Running) {
            //...
        }
    }

    override fun onFinished(result: FaceAutoCaptureResult) {
        //...
    }
}

UI Smile Liveness component

The SmileLivenessFragment class was moved to a new package, and both its API and configuration structure have changed. Existing configuration objects are not compatible with the new API and must be migrated to the new configuration model. Basic migration steps:

  • Replace import com.innovatrics.dot.face.liveness.smile.SmileLivenessFragment with import com.innovatrics.dot.face.liveness.smile.ui.SmileLivenessFragment.
  • Replace the method stopAsync(...) with the new method stop().
  • Update configuration provided by provideConfiguration() method.

Before

//...
import com.innovatrics.dot.face.liveness.smile.SmileLivenessFragment
//...

class BasicSmileLivenessFragment: SmileLivenessFragment {

    override fun provideConfiguration(): Configuration {
        return Configuration(
            cameraFacing = CameraFacing.FRONT,
            cameraPreviewScaleType = CameraPreviewScaleType.FIT,
            isTorchEnabled = false,
            isVideoCaptureEnabled = false,
            faceSizeRatioInterval = IntervalDouble(0.1, 0.3),
            isDetectionLayerVisible = true,
            query = FaceDetectionQuery(),
            sessionToken = "...",
            isCameraPreviewVisible = true,
            qualityAttributeThresholds = QualityAttributeThresholds(),
        )
    }
}

After

//...
import com.innovatrics.dot.face.liveness.smile.ui.SmileLivenessFragment
//...

class BasicSmileLivenessFragment: SmileLivenessFragment {
  
    override fun provideConfiguration(): Configuration {
        return Configuration(
            common = CommonConfiguration(
                sessionToken = "...",
            ),
            camera = CameraConfiguration(
                facing = CameraFacing.FRONT,
                previewScaleType = CameraPreviewScaleType.FIT,
                isTorchEnabled = false,
                isVideoCaptureEnabled = false,
                isPreviewVisible = true,
            ),
            faceLibraryComponent = FaceLibraryComponentConfiguration(
                faceSizeRatioInterval = IntervalDouble(0.1, 0.3),
                query = FaceDetectionQuery(),
            ),
            isDetectionLayerVisible = true,
            qualityAttributeThresholds = QualityAttributeThresholds(),
        )
    }
}

UI Multi-Range Liveness component

The configuration structure of the MultiRangeLivenessFragment has changed. Existing configuration objects are not compatible with the new API and must be migrated to the new configuration model. Basic migration steps:

  • Replace the method stopAsync(...) with the new method stop().
  • Update configuration provided by provideConfiguration() method.

Before

class BasicMultiRangeLivenessFragment: MultiRangeLivenessFragment {

    override fun provideConfiguration(): Configuration {
        return Configuration(
            challengeSequence = listOf(), // obtain challenge from DIS (Digital Identity Service)
            cameraFacing = CameraFacing.FRONT,
            cameraPreviewScaleType = CameraPreviewScaleType.FIT,
            isTorchEnabled = false,
            isVideoCaptureEnabled = false,
            isDetectionLayerVisible = true,
            query = FaceDetectionQuery(),
            sessionToken = "...",
            isCameraPreviewVisible = true,
        )
    }
}

After

class BasicMultiRangeLivenessFragment: MultiRangeLivenessFragment {
  
    override fun provideConfiguration(): Configuration {
        return Configuration(
            challengeSequence = listOf(), // obtain challenge from DIS (Digital Identity Service)
            common = CommonConfiguration(
                sessionToken = "...",
            ),
            camera = CameraConfiguration(
                facing = CameraFacing.FRONT,
                previewScaleType = CameraPreviewScaleType.FIT,
                isTorchEnabled = false,
                isVideoCaptureEnabled = false,
                isPreviewVisible = true,
            ),
            faceLibraryComponent = FaceLibraryComponentConfiguration(
                faceSizeRatioInterval = IntervalDouble(0.1, 0.3),
                query = FaceDetectionQuery(),
            ),
            isDetectionLayerVisible = false,
        )
    }
}

UI Eye Gaze Liveness component

WARNING: This component is deprecated in favour of UI Multi-Range Liveness.

The EyeGazeLivenessFragment class was moved to a new package, and both its API and configuration structure have changed. Existing configuration objects are not compatible with the new API and must be migrated to the new configuration model. Basic migration steps:

  • Replace import com.innovatrics.dot.face.liveness.eyegaze.EyeGazeLivenessFragment with import com.innovatrics.dot.face.liveness.eyegaze.ui.EyeGazeLivenessFragment.
  • Replace the method stopAsync(...) with the new method stop().
  • Update configuration provided by provideConfiguration() method.

Before

//...
import com.innovatrics.dot.face.liveness.eyegaze.EyeGazeLivenessFragment
//...

class BasicEyeGazeLivenessFragment: EyeGazeLivenessFragment {

    override fun provideConfiguration(): Configuration {
        return Configuration(
            cameraFacing = CameraFacing.FRONT,
            isTorchEnabled = false,
            isVideoCaptureEnabled = false,
            faceSizeRatioInterval = IntervalDouble(0.1, 0.3),
            corners = listOf(),
            minValidSamplesCount = 4,
            transitionType = Configuration.TransitionType.MOVE,
            transitionDurationMillis = 800,
            query = FaceDetectionQuery(),
            sessionToken = "...",
        )
    }
}

After

//...
import com.innovatrics.dot.face.liveness.eyegaze.ui.EyeGazeLivenessFragment
//...

class BasicEyeGazeLivenessFragment: EyeGazeLivenessFragment {
  
    override fun provideConfiguration(): Configuration {
        return Configuration(
            corners = listOf(),
            common = CommonConfiguration(
                sessionToken = "...",
            ),
            camera = CameraConfiguration(
                facing = CameraFacing.FRONT,
                previewScaleType = CameraPreviewScaleType.FIT,
                isTorchEnabled = false,
                isVideoCaptureEnabled = false,
                isPreviewVisible = true,
            ),
            faceLibraryComponent = FaceLibraryComponentConfiguration(
                faceSizeRatioInterval = IntervalDouble(0.1, 0.3),
                query = FaceDetectionQuery(),
            ),
            minValidSamplesCount = 4,
            transitionType = Configuration.TransitionType.MOVE,
            transitionDurationMillis = 800,
        )
    }
}

UI MagnifEye Liveness component

WARNING: This component is deprecated in favour of UI Multi-Range Liveness.

The MagnifEyeLivenessFragment class was moved to a new package, and both its API and configuration structure have changed. Existing configuration objects are not compatible with the new API and must be migrated to the new configuration model. Basic migration steps:

  • Replace import com.innovatrics.dot.face.liveness.magnifeye.MagnifEyeLivenessFragment with com.innovatrics.dot.face.liveness.magnifeye.ui.MagnifEyeLivenessFragment.
  • Replace the method stopAsync(...) with the new method stop().
  • Update configuration provided by provideConfiguration() method.

Before

//...
import com.innovatrics.dot.face.liveness.magnifeye.MagnifEyeLivenessFragment
//...

class BasicMagnifEyeLivenessFragment: MagnifEyeLivenessFragment {

    override fun provideConfiguration(): Configuration {
        return Configuration(
            cameraFacing = CameraFacing.FRONT,
            cameraPreviewScaleType = CameraPreviewScaleType.FIT,
            isTorchEnabled = false,
            isVideoCaptureEnabled = false,
            faceSizeRatioInterval = IntervalDouble(0.1, 0.3),
            isDetectionLayerVisible = false,
            query = FaceDetectionQuery(),
            sessionToken = "...",
            isCameraPreviewVisible = false,
        )
    }
}

After

//...
import com.innovatrics.dot.face.liveness.magnifeye.ui.MagnifEyeLivenessFragment
//...

class BasicMagnifEyeLivenessFragment: MagnifEyeLivenessFragment {
  
    override fun provideConfiguration(): Configuration {
        return Configuration(
            common = CommonConfiguration(
                sessionToken = "...",
            ),
            camera = CameraConfiguration(
                facing = CameraFacing.FRONT,
                previewScaleType = CameraPreviewScaleType.FIT,
                isTorchEnabled = false,
                isVideoCaptureEnabled = false,
                isPreviewVisible = true,
            ),
            faceLibraryComponent = FaceLibraryComponentConfiguration(
                faceSizeRatioInterval = IntervalDouble(0.1, 0.3),
                query = FaceDetectionQuery(),
            ),
            isDetectionLayerVisible = false,
        )
    }
}

Image

Several changes were applied to image-related functionality.

  • BgrRawImage has been replaced by the generic Image class.
  • BgrRawImageFactory has been replaced by ImageFactory.

Before

val image: BgrRawImage = BgrRawImageFactory.create(imageProxy)

After

val image: Image = ImageFactory.createBgrRawImage(imageProxy)