diff --git a/platform/jvm/replay/src/main/kotlin/io/bitdrift/capture/replay/internal/mappers/ViewMapper.kt b/platform/jvm/replay/src/main/kotlin/io/bitdrift/capture/replay/internal/mappers/ViewMapper.kt index 8b18845a..42eefb6e 100644 --- a/platform/jvm/replay/src/main/kotlin/io/bitdrift/capture/replay/internal/mappers/ViewMapper.kt +++ b/platform/jvm/replay/src/main/kotlin/io/bitdrift/capture/replay/internal/mappers/ViewMapper.kt @@ -63,7 +63,7 @@ internal class ViewMapper( private fun View.viewToReplayRect(): List { val list = mutableListOf() val resourceName = - if (id != View.NO_ID && id != ResourcesCompat.ID_NULL) { + if (isValidResId(this.id)) { try { resources.getResourceEntryName(this.id) } catch (ignore: Resources.NotFoundException) { @@ -72,7 +72,7 @@ internal class ViewMapper( "Failed to retrieve ID" } } else { - "no_resource_id" + "invalid_resource_id" } val type = viewMapperConfiguration.mapper[this.javaClass.simpleName] @@ -100,4 +100,15 @@ internal class ViewMapper( } return list } + + private fun isValidResId(resId: Int): Boolean { + @Suppress("MaxLineLength") + // the checks below are to avoid spamming logcat with errors emitted by the Android sub-system when calling resources.getResourceEntryName(invalidResourceId) + // see: https://cs.android.com/android/platform/superproject/main/+/6adcde7195b0c9efd344a2bec2412909ab66d047:frameworks/base/libs/androidfw/AssetManager2.cpp;l=657 + // lifted from: https://cs.android.com/android/platform/superproject/main/+/a2a9539615425091c7413249e5dc063009cf222b:frameworks/base/libs/androidfw/include/androidfw/ResourceUtils.h;l=62 + return resId != View.NO_ID && + resId != ResourcesCompat.ID_NULL && + (resId.toUInt() and 0x00ff0000u) != 0u && + (resId.toUInt() and 0xff000000u) != 0u + } }