<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">/*
 * 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.infer.annotation.Nullsafe;
import com.facebook.react.bridge.UiThreadUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Nullsafe(Nullsafe.Mode.LOCAL)
public class DebuggingOverlay extends View {

  private final Paint mTraceUpdatePaint = new Paint();
  private HashMap&lt;Integer, TraceUpdate&gt; mTraceUpdatesToDisplayMap = new HashMap();
  private HashMap&lt;Integer, Runnable&gt; mTraceUpdateIdToCleanupRunnableMap = new HashMap();

  private final Paint mHighlightedElementsPaint = new Paint();
  private List&lt;RectF&gt; mHighlightedElementsRectangles = new ArrayList&lt;&gt;();

  public DebuggingOverlay(Context context) {
    super(context);

    mTraceUpdatePaint.setStyle(Paint.Style.STROKE);
    mTraceUpdatePaint.setStrokeWidth(6);

    mHighlightedElementsPaint.setStyle(Paint.Style.FILL);
    mHighlightedElementsPaint.setColor(0xCCC8E6FF);
  }

  @UiThread
  public void setTraceUpdates(List&lt;TraceUpdate&gt; traceUpdates) {
    for (TraceUpdate traceUpdate : traceUpdates) {
      int traceUpdateId = traceUpdate.getId();
      if (mTraceUpdateIdToCleanupRunnableMap.containsKey(traceUpdateId)) {
        UiThreadUtil.removeOnUiThread(mTraceUpdateIdToCleanupRunnableMap.get(traceUpdateId));
        mTraceUpdateIdToCleanupRunnableMap.remove(traceUpdateId);
      }

      mTraceUpdatesToDisplayMap.put(traceUpdateId, traceUpdate);
    }

    invalidate();
  }

  @UiThread
  public void setHighlightedElementsRectangles(List&lt;RectF&gt; elementsRectangles) {
    mHighlightedElementsRectangles = elementsRectangles;
    invalidate();
  }

  @UiThread
  public void clearElementsHighlights() {
    mHighlightedElementsRectangles.clear();
    invalidate();
  }

  @Override
  public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    // Draw border outside of the given overlays to be aligned with web trace highlights
    for (TraceUpdate traceUpdate : mTraceUpdatesToDisplayMap.values()) {
      mTraceUpdatePaint.setColor(traceUpdate.getColor());
      canvas.drawRect(traceUpdate.getRectangle(), mTraceUpdatePaint);

      int traceUpdateId = traceUpdate.getId();
      Runnable block =
          () -&gt; {
            mTraceUpdatesToDisplayMap.remove(traceUpdateId);
            mTraceUpdateIdToCleanupRunnableMap.remove(traceUpdateId);

            invalidate();
          };

      if (!mTraceUpdateIdToCleanupRunnableMap.containsKey(traceUpdateId)) {
        mTraceUpdateIdToCleanupRunnableMap.put(traceUpdateId, block);
        UiThreadUtil.runOnUiThread(block, 2000);
      }
    }

    for (RectF elementRectangle : mHighlightedElementsRectangles) {
      canvas.drawRect(elementRectangle, mHighlightedElementsPaint);
    }
  }
}
</pre></body></html>