Skip to content

Commit 3918dd1

Browse files
huntiemeta-codesync[bot]
authored andcommitted
Fix potential bitmap leaks in FrameTimingsObserver (facebook#55652)
Summary: Pull Request resolved: facebook#55652 Address missing `recycle()` calls for bitmaps in frame timing screenshot capture on Android, which could leak either on exceptions or when window dimensions change. Changelog: [Internal] Reviewed By: rubennorte Differential Revision: D93863311 fbshipit-source-id: 3180f1be4df5b1dec2742d93e38886fb4db4e4d0
1 parent 47c7165 commit 3918dd1

1 file changed

Lines changed: 12 additions & 8 deletions

File tree

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/inspector/FrameTimingsObserver.kt

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ internal class FrameTimingsObserver(
7373
if (it.width == width && it.height == height) {
7474
it
7575
} else {
76+
it.recycle()
7677
null
7778
}
7879
} ?: Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also { bitmapBuffer = it }
@@ -83,26 +84,29 @@ internal class FrameTimingsObserver(
8384
{ copyResult ->
8485
if (copyResult == PixelCopy.SUCCESS) {
8586
CoroutineScope(Dispatchers.Default).launch {
87+
var scaledBitmap: Bitmap? = null
8688
try {
8789
val scaleFactor = 0.25f
8890
val scaledWidth = (width * scaleFactor).toInt()
8991
val scaledHeight = (height * scaleFactor).toInt()
90-
val scaledBitmap =
91-
Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true)
92+
scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true)
9293

93-
val outputStream = ByteArrayOutputStream()
9494
val compressFormat =
9595
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
9696
Bitmap.CompressFormat.WEBP_LOSSY
9797
else Bitmap.CompressFormat.WEBP
98-
scaledBitmap.compress(compressFormat, 0, outputStream)
99-
val bytes = outputStream.toByteArray()
100-
val base64 = Base64.encodeToString(bytes, Base64.NO_WRAP)
101-
continuation.resume(base64)
10298

103-
scaledBitmap.recycle()
99+
val base64 =
100+
ByteArrayOutputStream().use { outputStream ->
101+
scaledBitmap.compress(compressFormat, 0, outputStream)
102+
Base64.encodeToString(outputStream.toByteArray(), Base64.NO_WRAP)
103+
}
104+
105+
continuation.resume(base64)
104106
} catch (e: Exception) {
105107
continuation.resume(null)
108+
} finally {
109+
scaledBitmap?.recycle()
106110
}
107111
}
108112
} else {

0 commit comments

Comments
 (0)