package com.biopassid.facesdkreactnative import android.util.Base64 import android.util.Log import br.com.biopassid.facesdk.Face import br.com.biopassid.facesdk.FaceCallback import br.com.biopassid.facesdk.FaceRecognition import br.com.biopassid.facesdk.model.FaceAttributes import br.com.biopassid.facesdk.model.FaceExtract import br.com.biopassid.facesdk.model.FaceImage import br.com.biopassid.facesdk.model.FaceVerify import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReactContextBaseJavaModule import com.facebook.react.bridge.ReactMethod import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReactContext import com.facebook.react.bridge.ReadableMap import com.facebook.react.bridge.WritableMap import com.facebook.react.modules.core.DeviceEventManagerModule class FaceSdkReactNativeModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { private var listenerCount = 0 private var faceRecognition: FaceRecognition? = null override fun getName(): String { return NAME } @ReactMethod fun addListener(eventName: String) { if (listenerCount == 0) { // Set up any upstream listeners or background tasks as necessary } listenerCount += 1 } @ReactMethod fun removeListeners(count: Int) { listenerCount -= count if (listenerCount == 0) { // Remove upstream listeners, stop unnecessary background tasks } } @ReactMethod fun takeFace(faceConfig: ReadableMap, promise: Promise) { try { val config = Utils.mapToFaceConfig(currentActivity, faceConfig) val callback = object : FaceCallback { override fun onFaceCapture(faceImage: FaceImage, faceAttributes: FaceAttributes?) { val nativeMap = Utils.onFaceCaptureToNativeMap(faceImage.imageBase64, faceAttributes) sendEvent(reactApplicationContext, "face-sdk-react-native/onFaceCapture", nativeMap) } override fun onFaceDetected(faceAttributes: FaceAttributes) { val nativeMap = Utils.onFaceDetectedToNativeMap(faceAttributes) Log.d(TAG, "onFaceDetected: $nativeMap") sendEvent(reactApplicationContext, "face-sdk-react-native/onFaceDetected", nativeMap) } } Face.takeFace(currentActivity, config, callback) promise.resolve(null) } catch (e: Exception) { Log.e(TAG, e.message.toString()) promise.reject("Error when calling Face SDK React Native", e) } } @ReactMethod fun startRecognition(licenseKey: String, promise: Promise) { try { if (currentActivity != null) { faceRecognition = FaceRecognition.getInstance(currentActivity!!, licenseKey) } promise.resolve(null) } catch (e: Exception) { Log.e(TAG, e.message.toString()) promise.reject("Error when calling initRecognition", e) } } @ReactMethod fun closeRecognition(promise: Promise) { try { faceRecognition?.close() faceRecognition = null promise.resolve(null) } catch (e: Exception) { Log.e(TAG, e.message.toString()) promise.reject("Error when calling closeRecognition", e) } } @ReactMethod fun extract(artifact: String, promise: Promise) { try { faceRecognition?.extract(artifact, object : FaceRecognition.ExtractCallback { override fun onExtract(faceExtract: FaceExtract?) { var extractMap: Map? = null if (faceExtract != null) { val templateBase64 = Base64.encodeToString(faceExtract.template, Base64.NO_WRAP) extractMap = hashMapOf( "status" to faceExtract.status, "template" to templateBase64, ) } val nativeMap = Arguments.makeNativeMap(extractMap) promise.resolve(nativeMap) } }) } catch (e: Exception) { Log.e(TAG, e.message.toString()) promise.reject("Error when calling extract", e) } } @ReactMethod fun verify(templateA: String, templateB: String, promise: Promise) { try { val byteArrayTemplateA = Base64.decode(templateA, Base64.NO_WRAP) val byteArrayTemplateB = Base64.decode(templateB, Base64.NO_WRAP) faceRecognition?.verify( byteArrayTemplateA, byteArrayTemplateB, object : FaceRecognition.VerifyCallback { override fun onVerify(faceVerify: FaceVerify?) { var verifyMap: Map? = null if (faceVerify != null) { verifyMap = hashMapOf( "isGenuine" to faceVerify.isGenuine, "score" to faceVerify.score, ) } val nativeMap = Arguments.makeNativeMap(verifyMap) promise.resolve(nativeMap) } }) } catch (e: Exception) { Log.e(TAG, e.message.toString()) promise.reject("Error when calling verify", e) } } private fun sendEvent(reactContext: ReactContext, eventName: String, params: WritableMap) { reactContext .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) .emit(eventName, params) } companion object { const val NAME = "FaceSdkReactNative" private val TAG = FaceSdkReactNativeModule::class.java.simpleName } }