Skip to content

Commit

Permalink
Merge branch 'main' into feat/fix-retry-bug
Browse files Browse the repository at this point in the history
  • Loading branch information
jumaallan authored Sep 6, 2024
2 parents acf0d79 + 3608d10 commit 697958f
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 38 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
## Unreleased

* Fixed upload bug to retry in case a job already exists but zip was not uploaded
* Changed MLKit download modules to throw an exception explicitly if download fails

## 10.2.6

* Make document captured image confirmation to be optional

## 10.2.5

Expand Down
83 changes: 59 additions & 24 deletions lib/src/main/java/com/smileidentity/SmileID.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE
import android.provider.Settings.Secure
import com.google.android.gms.common.moduleinstall.ModuleInstall
import com.google.android.gms.common.moduleinstall.ModuleInstallRequest
import com.google.android.gms.tasks.Tasks
import com.google.mlkit.common.sdkinternal.MlKitContext
import com.google.mlkit.vision.face.FaceDetection
import com.serjltt.moshi.adapters.FallbackEnum
Expand Down Expand Up @@ -54,10 +55,13 @@ import io.sentry.Breadcrumb
import io.sentry.SentryLevel
import java.net.URL
import java.util.concurrent.TimeUnit
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
Expand Down Expand Up @@ -127,7 +131,6 @@ object SmileID {
if (enableCrashReporting) {
SmileIDCrashReporting.enable(isInDebugMode)
}
requestFaceDetectionModuleInstallation(context)

SmileID.useSandbox = useSandbox
val url = if (useSandbox) config.sandboxBaseUrl else config.prodBaseUrl
Expand All @@ -147,6 +150,14 @@ object SmileID {
fileSavePath = context.getDir("SmileID", MODE_PRIVATE).absolutePath
// ANDROID_ID may be null. Since Android 8, each app has a different value
Secure.getString(context.contentResolver, Secure.ANDROID_ID)?.let { fingerprint = it }

val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
Timber.d("Face Detection Module Exception : ${throwable.message}")
throw throwable
}

val scope = CoroutineScope(Dispatchers.IO + SupervisorJob() + exceptionHandler)
scope.launch { requestFaceDetectionModuleInstallation(context) }
}

/**
Expand Down Expand Up @@ -486,29 +497,53 @@ object SmileID {
/**
* Request Google Play Services to install the Face Detection Module, if not already installed.
*/
private fun requestFaceDetectionModuleInstallation(context: Context) {
// see: https://github.com/googlesamples/mlkit/issues/264
MlKitContext.initializeIfNeeded(context)
val moduleInstallRequest = ModuleInstallRequest.newBuilder()
.addApi(FaceDetection.getClient())
.setListener {
val message = "Face Detection install status: " +
"errorCode=${it.errorCode}, " +
"installState=${it.installState}, " +
"bytesDownloaded=${it.progressInfo?.bytesDownloaded}, " +
"totalBytesToDownload=${it.progressInfo?.totalBytesToDownload}"
Timber.d(message)
SmileIDCrashReporting.hub.addBreadcrumb(message)
}.build()

ModuleInstall.getClient(context)
.installModules(moduleInstallRequest)
.addOnSuccessListener {
Timber.d("Face Detection install success: ${it.areModulesAlreadyInstalled()}")
}
.addOnFailureListener {
Timber.w(it, "Face Detection install failed")
SmileIDCrashReporting.hub.addBreadcrumb("Face Detection install failed")
@Suppress("ktlint:standard:max-line-length")
private suspend fun requestFaceDetectionModuleInstallation(context: Context) {
withContext(Dispatchers.IO) {
try {
// see: https://github.com/googlesamples/mlkit/issues/264
MlKitContext.initializeIfNeeded(context)

val moduleInstallRequest = ModuleInstallRequest.newBuilder()
.addApi(FaceDetection.getClient())
.setListener {
val message = "Face Detection install status: " +
"errorCode=${it.errorCode}, " +
"installState=${it.installState}, " +
"bytesDownloaded=${it.progressInfo?.bytesDownloaded}, " +
"totalBytesToDownload=${it.progressInfo?.totalBytesToDownload}"
Timber.d(message)
SmileIDCrashReporting.hub.addBreadcrumb(message)
}.build()

val installTask =
ModuleInstall.getClient(context).installModules(moduleInstallRequest)

Tasks.await(installTask)

if (installTask.isSuccessful) {
Timber.d(
"Face Detection install success: " +
"${installTask.result.areModulesAlreadyInstalled()}",
)
} else {
val exception = installTask.exception
?: Exception(
"An error occurred during Face Detection module installation." +
"See the guide here to use the bundled version " +
"https://developers.google.com/ml-kit/vision/face-detection/android",
)
Timber.w(exception, "Face Detection install failed")
SmileIDCrashReporting.hub.addBreadcrumb("Face Detection install failed")
throw exception
}
} catch (exception: Exception) {
Timber.e(exception, "Error during Face Detection module installation")
SmileIDCrashReporting.hub.addBreadcrumb(
"Error during Face Detection module installation: ${exception.message}",
)
throw exception
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ fun DocumentCaptureScreen(
onConfirm: (File) -> Unit,
onError: (Throwable) -> Unit,
modifier: Modifier = Modifier,
showConfirmation: Boolean = true,
metadata: SnapshotStateList<Metadatum> = LocalMetadata.current,
onSkip: () -> Unit = { },
viewModel: DocumentCaptureViewModel = viewModel(
Expand Down Expand Up @@ -166,20 +167,26 @@ fun DocumentCaptureScreen(
ColorPainter(Color.Black)
}
}
ImageCaptureConfirmationDialog(
titleText = stringResource(id = R.string.si_doc_v_confirmation_dialog_title),
subtitleText = stringResource(id = R.string.si_doc_v_confirmation_dialog_subtitle),
painter = painter,
scaleFactor = PREVIEW_SCALE_FACTOR,
confirmButtonText = stringResource(
id = R.string.si_doc_v_confirmation_dialog_confirm_button,
),
onConfirm = { viewModel.onConfirm(documentImageToConfirm, onConfirm) },
retakeButtonText = stringResource(
id = R.string.si_doc_v_confirmation_dialog_retake_button,
),
onRetake = viewModel::onRetry,
)
if (showConfirmation) {
ImageCaptureConfirmationDialog(
titleText = stringResource(id = R.string.si_doc_v_confirmation_dialog_title),
subtitleText = stringResource(
id = R.string.si_doc_v_confirmation_dialog_subtitle,
),
painter = painter,
scaleFactor = PREVIEW_SCALE_FACTOR,
confirmButtonText = stringResource(
id = R.string.si_doc_v_confirmation_dialog_confirm_button,
),
onConfirm = { viewModel.onConfirm(documentImageToConfirm, onConfirm) },
retakeButtonText = stringResource(
id = R.string.si_doc_v_confirmation_dialog_retake_button,
),
onRetake = viewModel::onRetry,
)
} else {
viewModel.onConfirm(documentImageToConfirm, onConfirm)
}
}

else -> {
Expand Down

0 comments on commit 697958f

Please sign in to comment.