Status Update
Comments
[Deleted User] <[Deleted User]> #2
Project: platform/frameworks/support
Branch: androidx-main
commit b93b6044308aafa2361f69fe55cd24dbf7b016e6
Author: elifbilgin <elifbilgin@google.com>
Date: Wed Aug 02 08:14:41 2023
Converting `room-common` build files to be AndroidX Multiplatform.
Bug: 299168035
Test: Existing tests
Change-Id: I2b0c00a0d978b45745bf7e94628e2b1ebc6cb66e
M room/room-common/build.gradle
M room/room-common/src/commonMain/kotlin/androidx/room/AmbiguousColumnResolver.kt
M room/room-common/src/commonMain/kotlin/androidx/room/AutoMigration.kt
M room/room-common/src/commonMain/kotlin/androidx/room/BuiltInTypeConverters.kt
M room/room-common/src/commonMain/kotlin/androidx/room/ColumnInfo.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Dao.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Database.kt
M room/room-common/src/commonMain/kotlin/androidx/room/DatabaseView.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Delete.kt
M room/room-common/src/commonMain/kotlin/androidx/room/DeleteColumn.kt
M room/room-common/src/commonMain/kotlin/androidx/room/DeleteTable.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Embedded.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Entity.kt
M room/room-common/src/commonMain/kotlin/androidx/room/ForeignKey.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Fts3.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Fts4.kt
M room/room-common/src/commonMain/kotlin/androidx/room/FtsOptions.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Ignore.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Index.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Insert.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Junction.kt
M room/room-common/src/commonMain/kotlin/androidx/room/MapColumn.kt
M room/room-common/src/commonMain/kotlin/androidx/room/MapInfo.kt
M room/room-common/src/commonMain/kotlin/androidx/room/OnConflictStrategy.kt
M room/room-common/src/commonMain/kotlin/androidx/room/PrimaryKey.kt
M room/room-common/src/commonMain/kotlin/androidx/room/ProvidedAutoMigrationSpec.kt
M room/room-common/src/commonMain/kotlin/androidx/room/ProvidedTypeConverter.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Query.kt
M room/room-common/src/commonMain/kotlin/androidx/room/RawQuery.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Relation.kt
M room/room-common/src/commonMain/kotlin/androidx/room/RenameColumn.kt
M room/room-common/src/commonMain/kotlin/androidx/room/RenameTable.kt
M room/room-common/src/commonMain/kotlin/androidx/room/RewriteQueriesToDropUnusedColumns.kt
M room/room-common/src/commonMain/kotlin/androidx/room/RoomMasterTable.kt
M room/room-common/src/commonMain/kotlin/androidx/room/RoomWarnings.kt
M room/room-common/src/commonMain/kotlin/androidx/room/SkipQueryVerification.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Transaction.kt
M room/room-common/src/commonMain/kotlin/androidx/room/TypeConverter.kt
M room/room-common/src/commonMain/kotlin/androidx/room/TypeConverters.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Update.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Upsert.kt
M room/room-common/src/commonTest/kotlin/androidx/room/AmbiguousColumnResolverTest.kt
M room/room-common/src/commonTest/kotlin/androidx/room/AnnotationRetentionPolicyTest.kt
M settings.gradle
https://android-review.googlesource.com/2689826
Branch: androidx-main
commit b93b6044308aafa2361f69fe55cd24dbf7b016e6
Author: elifbilgin <elifbilgin@google.com>
Date: Wed Aug 02 08:14:41 2023
Converting `room-common` build files to be AndroidX Multiplatform.
Bug: 299168035
Test: Existing tests
Change-Id: I2b0c00a0d978b45745bf7e94628e2b1ebc6cb66e
M room/room-common/build.gradle
M room/room-common/src/commonMain/kotlin/androidx/room/AmbiguousColumnResolver.kt
M room/room-common/src/commonMain/kotlin/androidx/room/AutoMigration.kt
M room/room-common/src/commonMain/kotlin/androidx/room/BuiltInTypeConverters.kt
M room/room-common/src/commonMain/kotlin/androidx/room/ColumnInfo.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Dao.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Database.kt
M room/room-common/src/commonMain/kotlin/androidx/room/DatabaseView.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Delete.kt
M room/room-common/src/commonMain/kotlin/androidx/room/DeleteColumn.kt
M room/room-common/src/commonMain/kotlin/androidx/room/DeleteTable.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Embedded.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Entity.kt
M room/room-common/src/commonMain/kotlin/androidx/room/ForeignKey.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Fts3.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Fts4.kt
M room/room-common/src/commonMain/kotlin/androidx/room/FtsOptions.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Ignore.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Index.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Insert.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Junction.kt
M room/room-common/src/commonMain/kotlin/androidx/room/MapColumn.kt
M room/room-common/src/commonMain/kotlin/androidx/room/MapInfo.kt
M room/room-common/src/commonMain/kotlin/androidx/room/OnConflictStrategy.kt
M room/room-common/src/commonMain/kotlin/androidx/room/PrimaryKey.kt
M room/room-common/src/commonMain/kotlin/androidx/room/ProvidedAutoMigrationSpec.kt
M room/room-common/src/commonMain/kotlin/androidx/room/ProvidedTypeConverter.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Query.kt
M room/room-common/src/commonMain/kotlin/androidx/room/RawQuery.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Relation.kt
M room/room-common/src/commonMain/kotlin/androidx/room/RenameColumn.kt
M room/room-common/src/commonMain/kotlin/androidx/room/RenameTable.kt
M room/room-common/src/commonMain/kotlin/androidx/room/RewriteQueriesToDropUnusedColumns.kt
M room/room-common/src/commonMain/kotlin/androidx/room/RoomMasterTable.kt
M room/room-common/src/commonMain/kotlin/androidx/room/RoomWarnings.kt
M room/room-common/src/commonMain/kotlin/androidx/room/SkipQueryVerification.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Transaction.kt
M room/room-common/src/commonMain/kotlin/androidx/room/TypeConverter.kt
M room/room-common/src/commonMain/kotlin/androidx/room/TypeConverters.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Update.kt
M room/room-common/src/commonMain/kotlin/androidx/room/Upsert.kt
M room/room-common/src/commonTest/kotlin/androidx/room/AmbiguousColumnResolverTest.kt
M room/room-common/src/commonTest/kotlin/androidx/room/AnnotationRetentionPolicyTest.kt
M settings.gradle
Description
Version used: 1.0.0-alpha02
Devices/Android versions reproduced on: Samsung SM-G965U Android 9
This one is being reported only in the wild, and we haven't reproduced it yet. The issue seems to be that the androidx.biometric library can sometimes disobey the @Nonnull annotation in the callback, leading to an internal Kotlin exception when the Java -> Kotlin boundary is crossed.
We have been seeing exception traces of the following type in our application:
Fatal Exception: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.d.b.j.b, parameter errString
at com.varomoney.varo.system.repository.BiometricsRepository$makeAuthenticationCallback$2.$onSuccess(Unknown Source:2)
at androidx.biometrics.BiometricFragment$1$1.run(BiometricFragment.java:66)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:6981)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
When looking at our Kotlin code, we have:
BiometricPrompt.AuthenticationCallback {
return object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
onSuccess(result.cryptoObject?.cipher)
}
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
Timber.e("onAuthenticationError $errorCode $errString")
onError(AuthenticationError(errorCode, errString))
}
override fun onAuthenticationFailed() {
Timber.v("onAuthenticationFailed")
}
}
}
The exception is happening on:
override fun onAuthenticationError(errorCode: Int, errString: CharSequence)
Which is implemented in the base Java class:
public void onAuthenticationError(@BiometricError int errorCode,
@NonNull CharSequence errString) {}
So, errString should never be null. However, probably due to something interesting inside, the Samsung implementation of biometrics in Android 9 (this is only a guess and not meant to be disparaging), sometimes, the errString that comes back IS null. In Java this just gets send on down to Kotlin, which catches it as an error.
What I've had to do is make a Java class like the following:
import androidx.annotation.Nullable;
import androidx.biometrics.BiometricPrompt;
/**
* This class is here to allow the errString to be nullable because the library ignores its own
* annotations and sends something that might be null.
*/
public abstract class AuthenticationCallback extends BiometricPrompt.AuthenticationCallback {
@Override
public void onAuthenticationError(int errorCode, @Nullable CharSequence errString) {
}
}
This allows me to change my code to:
private fun makeAuthenticationCallback(
onSuccess: (Cipher?) -> Unit,
onError: (error: AuthenticationError) -> Unit = {}
): BiometricPrompt.AuthenticationCallback {
return object : AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
onSuccess(result.cryptoObject?.cipher)
}
override fun onAuthenticationError(errorCode: Int, errString: CharSequence?) {
Timber.e("onAuthenticationError $errorCode $errString")
onError(AuthenticationError(errorCode, errString))
}
override fun onAuthenticationFailed() {
Timber.v("onAuthenticationFailed")
}
}
}
And my AuthenticationError class to:
data class AuthenticationError(val errorCode: Int, val errorString: CharSequence?)
We don't use the errorString anyway, as the errorCode is sufficient. So this will prevent, I would hope, the Kotlin code from complaining about a null being sent for errorString.
Hope this helps.