// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.embedding.engine.renderer;

import static io.flutter.Build.API_LEVELS;

import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.hardware.HardwareBuffer;
import android.hardware.SyncFence;
import android.media.Image;
import android.media.ImageReader;
import android.os.Build;
import android.os.Handler;
import android.view.Surface;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import io.flutter.Log;
import io.flutter.embedding.engine.FlutterJNI;
import io.flutter.view.TextureRegistry;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Represents the rendering responsibilities of a {@code FlutterEngine}.
 *
 * <p>{@code FlutterRenderer} works in tandem with a provided {@link RenderSurface} to paint Flutter
 * pixels to an Android {@code View} hierarchy.
 *
 * <p>{@code FlutterRenderer} manages textures for rendering, and forwards some Java calls to native
 * Flutter code via JNI. The corresponding {@link RenderSurface} provides the Android {@link
 * Surface} that this renderer paints.
 *
 * <p>{@link io.flutter.embedding.android.FlutterSurfaceView} and {@link
 * io.flutter.embedding.android.FlutterTextureView} are implementations of {@link RenderSurface}.
 */
public class FlutterRenderer implements TextureRegistry {
  /**
   * Whether to always use GL textures for {@link FlutterRenderer#createSurfaceProducer()}.
   *
   * <p>This is a debug-only API intended for local development. For example, when using a newer
   * Android device (that normally would use {@link ImageReaderSurfaceProducer}, but wanting to test
   * the OpenGLES/{@link SurfaceTextureSurfaceProducer} code branch. This flag has undefined
   * behavior if set to true while running in a Vulkan (Impeller) context.
   */
  @VisibleForTesting public static boolean debugForceSurfaceProducerGlTextures = false;

  private static final String TAG = "FlutterRenderer";

  @NonNull private final FlutterJNI flutterJNI;
  @NonNull private final AtomicLong nextTextureId = new AtomicLong(0L);
  @Nullable private Surface surface;
  private boolean isDisplayingFlutterUi = false;
  private final Handler handler = new Handler();

  @NonNull
  private final Set<WeakReference<TextureRegistry.OnTrimMemoryListener>> onTrimMemoryListeners =
      new HashSet<>();

  @NonNull
  private final FlutterUiDisplayListener flutterUiDisplayListener =
      new FlutterUiDisplayListener() {
        @Override
        public void onFlutterUiDisplayed() {
          isDisplayingFlutterUi = true;
        }

        @Override
        public void onFlutterUiNoLongerDisplayed() {
          isDisplayingFlutterUi = false;
        }
      };

  public FlutterRenderer(@NonNull FlutterJNI flutterJNI) {
    this.flutterJNI = flutterJNI;
    this.flutterJNI.addIsDisplayingFlutterUiListener(flutterUiDisplayListener);
  }

  /**
   * Returns true if this {@code FlutterRenderer} is painting pixels to an Android {@code View}
   * hierarchy, false otherwise.
   */
  public boolean isDisplayingFlutterUi() {
    return isDisplayingFlutterUi;
  }

  /**
   * Adds a listener that is invoked whenever this {@code FlutterRenderer} starts and stops painting
   * pixels to an Android {@code View} hierarchy.
   */
  public void addIsDisplayingFlutterUiListener(@NonNull FlutterUiDisplayListener listener) {
    flutterJNI.addIsDisplayingFlutterUiListener(listener);

    if (isDisplayingFlutterUi) {
      listener.onFlutterUiDisplayed();
    }
  }

  /**
   * Removes a listener added via {@link
   * #addIsDisplayingFlutterUiListener(FlutterUiDisplayListener)}.
   */
  public void removeIsDisplayingFlutterUiListener(@NonNull FlutterUiDisplayListener listener) {
    flutterJNI.removeIsDisplayingFlutterUiListener(listener);
  }

  private void clearDeadListeners() {
    final Iterator<WeakReference<OnTrimMemoryListener>> iterator = onTrimMemoryListeners.iterator();
    while (iterator.hasNext()) {
      WeakReference<OnTrimMemoryListener> listenerRef = iterator.next();
      final OnTrimMemoryListener listener = listenerRef.get();
      if (listener == null) {
        iterator.remove();
      }
    }
  }

  /** Adds a listener that is invoked when a memory pressure warning was forward. */
  @VisibleForTesting
  /* package */ void addOnTrimMemoryListener(@NonNull OnTrimMemoryListener listener) {
    // Purge dead listener to avoid accumulating.
    clearDeadListeners();
    onTrimMemoryListeners.add(new WeakReference<>(listener));
  }

  /**
   * Removes a {@link OnTrimMemoryListener} that was added with {@link
   * #addOnTrimMemoryListener(OnTrimMemoryListener)}.
   */
  @VisibleForTesting
  /* package */ void removeOnTrimMemoryListener(@NonNull OnTrimMemoryListener listener) {
    for (WeakReference<OnTrimMemoryListener> listenerRef : onTrimMemoryListeners) {
      if (listenerRef.get() == listener) {
        onTrimMemoryListeners.remove(listenerRef);
        break;
      }
    }
  }

  // ------ START TextureRegistry IMPLEMENTATION -----

  /**
   * Creates and returns a new external texture {@link SurfaceProducer} managed by the Flutter
   * engine that is also made available to Flutter code.
   */
  @NonNull
  @Override
  public SurfaceProducer createSurfaceProducer() {
    // Prior to Impeller, Flutter on Android *only* ran on OpenGLES (via Skia). That
    // meant that
    // plugins (i.e. end-users) either explicitly created a SurfaceTexture (via
    // createX/registerX) or an ImageTexture (via createX/registerX).
    //
    // In an Impeller world, which for the first time uses (if available) a Vulkan
    // rendering
    // backend, it is no longer possible (at least not trivially) to render an
    // OpenGLES-provided
    // texture (SurfaceTexture) in a Vulkan context.
    //
    // This function picks the "best" rendering surface based on the Android
    // runtime, and
    // provides a consumer-agnostic SurfaceProducer (which in turn vends a Surface),
    // and has
    // plugins (i.e. end-users) use the Surface instead, letting us "hide" the
    // consumer-side
    // of the implementation.
    //
    // tl;dr: If ImageTexture is available, we use it, otherwise we use a
    // SurfaceTexture.
    // Coincidentally, if ImageTexture is available, we are also on an Android
    // version that is
    // running Vulkan, so we don't have to worry about it not being supported.
    final SurfaceProducer entry;
    if (!debugForceSurfaceProducerGlTextures && Build.VERSION.SDK_INT >= API_LEVELS.API_29) {
      final long id = nextTextureId.getAndIncrement();
      final ImageReaderSurfaceProducer producer = new ImageReaderSurfaceProducer(id);
      registerImageTexture(id, producer);
      addOnTrimMemoryListener(producer);
      Log.v(TAG, "New ImageReaderSurfaceProducer ID: " + id);
      entry = producer;
    } else {
      // TODO(matanlurey): Actually have the class named "*Producer" to well, produce
      // something. This is a code smell, but does guarantee the paths for both
      // createSurfaceTexture and createSurfaceProducer doesn't diverge. As we get more
      // confident in this API and any possible bugs (and have tests to check we don't
      // regress), reconsider this pattern.
      final SurfaceTextureEntry texture = createSurfaceTexture();
      final SurfaceTextureSurfaceProducer producer =
          new SurfaceTextureSurfaceProducer(texture.id(), handler, flutterJNI, texture);
      Log.v(TAG, "New SurfaceTextureSurfaceProducer ID: " + texture.id());
      entry = producer;
    }
    return entry;
  }

  /**
   * Creates and returns a new {@link SurfaceTexture} managed by the Flutter engine that is also
   * made available to Flutter code.
   */
  @NonNull
  @Override
  public SurfaceTextureEntry createSurfaceTexture() {
    Log.v(TAG, "Creating a SurfaceTexture.");
    final SurfaceTexture surfaceTexture = new SurfaceTexture(0);
    return registerSurfaceTexture(surfaceTexture);
  }

  /**
   * Registers and returns a {@link SurfaceTexture} managed by the Flutter engine that is also made
   * available to Flutter code.
   */
  @NonNull
  @Override
  public SurfaceTextureEntry registerSurfaceTexture(@NonNull SurfaceTexture surfaceTexture) {
    return registerSurfaceTexture(nextTextureId.getAndIncrement(), surfaceTexture);
  }

  /**
   * Similar to {@link FlutterRenderer#registerSurfaceTexture} but with an existing @{code
   * textureId}.
   *
   * @param surfaceTexture Surface texture to wrap.
   * @param textureId A texture ID already created that should be assigned to the surface texture.
   */
  @NonNull
  private SurfaceTextureEntry registerSurfaceTexture(
      long textureId, @NonNull SurfaceTexture surfaceTexture) {
    surfaceTexture.detachFromGLContext();
    final SurfaceTextureRegistryEntry entry =
        new SurfaceTextureRegistryEntry(textureId, surfaceTexture);
    Log.v(TAG, "New SurfaceTexture ID: " + entry.id());
    registerTexture(entry.id(), entry.textureWrapper());
    addOnTrimMemoryListener(entry);
    return entry;
  }

  @NonNull
  @Override
  public ImageTextureEntry createImageTexture() {
    final ImageTextureRegistryEntry entry =
        new ImageTextureRegistryEntry(nextTextureId.getAndIncrement());
    Log.v(TAG, "New ImageTextureEntry ID: " + entry.id());
    registerImageTexture(entry.id(), entry);
    return entry;
  }

  @Override
  public void onTrimMemory(int level) {
    final Iterator<WeakReference<OnTrimMemoryListener>> iterator = onTrimMemoryListeners.iterator();
    while (iterator.hasNext()) {
      WeakReference<OnTrimMemoryListener> listenerRef = iterator.next();
      final OnTrimMemoryListener listener = listenerRef.get();
      if (listener != null) {
        listener.onTrimMemory(level);
      } else {
        // Purge cleared refs to avoid accumulating a lot of dead listener
        iterator.remove();
      }
    }
  }

  final class SurfaceTextureRegistryEntry
      implements TextureRegistry.SurfaceTextureEntry, TextureRegistry.OnTrimMemoryListener {
    private final long id;
    @NonNull private final SurfaceTextureWrapper textureWrapper;
    private boolean released;
    @Nullable private OnTrimMemoryListener trimMemoryListener;
    @Nullable private OnFrameConsumedListener frameConsumedListener;

    SurfaceTextureRegistryEntry(long id, @NonNull SurfaceTexture surfaceTexture) {
      this.id = id;
      Runnable onFrameConsumed =
          () -> {
            if (frameConsumedListener != null) {
              frameConsumedListener.onFrameConsumed();
            }
          };
      this.textureWrapper = new SurfaceTextureWrapper(surfaceTexture, onFrameConsumed);

      // Even though we make sure to unregister the callback before releasing, as of
      // Android O, SurfaceTexture has a data race when accessing the callback, so the
      // callback may still be called by a stale reference after released==true and
      // mNativeView==null.
      SurfaceTexture.OnFrameAvailableListener onFrameListener =
          texture -> {
            if (released || !flutterJNI.isAttached()) {
              // Even though we make sure to unregister the callback before releasing, as of
              // Android O, SurfaceTexture has a data race when accessing the callback, so the
              // callback may still be called by a stale reference after released==true and
              // mNativeView==null.
              return;
            }
            textureWrapper.markDirty();
            scheduleEngineFrame();
          };
      // The callback relies on being executed on the UI thread (unsynchronised read of
      // mNativeView and also the engine code check for platform thread in
      // Shell::OnPlatformViewMarkTextureFrameAvailable), so we explicitly pass a Handler for the
      // current thread.
      this.surfaceTexture().setOnFrameAvailableListener(onFrameListener, new Handler());
    }

    @Override
    public void onTrimMemory(int level) {
      if (trimMemoryListener != null) {
        trimMemoryListener.onTrimMemory(level);
      }
    }

    private void removeListener() {
      removeOnTrimMemoryListener(this);
    }

    @NonNull
    public SurfaceTextureWrapper textureWrapper() {
      return textureWrapper;
    }

    @Override
    @NonNull
    public SurfaceTexture surfaceTexture() {
      return textureWrapper.surfaceTexture();
    }

    @Override
    public long id() {
      return id;
    }

    @Override
    public void release() {
      if (released) {
        return;
      }
      Log.v(TAG, "Releasing a SurfaceTexture (" + id + ").");
      textureWrapper.release();
      unregisterTexture(id);
      removeListener();
      released = true;
    }

    @Override
    protected void finalize() throws Throwable {
      try {
        if (released) {
          return;
        }

        handler.post(new TextureFinalizerRunnable(id, flutterJNI));
      } finally {
        super.finalize();
      }
    }

    @Override
    public void setOnFrameConsumedListener(@Nullable OnFrameConsumedListener listener) {
      frameConsumedListener = listener;
    }

    @Override
    public void setOnTrimMemoryListener(@Nullable OnTrimMemoryListener listener) {
      trimMemoryListener = listener;
    }
  }

  static final class TextureFinalizerRunnable implements Runnable {
    private final long id;
    private final FlutterJNI flutterJNI;

    TextureFinalizerRunnable(long id, @NonNull FlutterJNI flutterJNI) {
      this.id = id;
      this.flutterJNI = flutterJNI;
    }

    @Override
    public void run() {
      if (!flutterJNI.isAttached()) {
        return;
      }
      Log.v(TAG, "Releasing a Texture (" + id + ").");
      flutterJNI.unregisterTexture(id);
    }
  }

  // Keep a queue of ImageReaders.
  // Each ImageReader holds acquired Images.
  // When we acquire the next image, close any ImageReaders that don't have any
  // more pending images.
  @Keep
  @TargetApi(API_LEVELS.API_29)
  final class ImageReaderSurfaceProducer
      implements TextureRegistry.SurfaceProducer,
          TextureRegistry.ImageConsumer,
          TextureRegistry.OnTrimMemoryListener {
    private static final String TAG = "ImageReaderSurfaceProducer";
    private static final int MAX_IMAGES = 5;

    // Flip when debugging to see verbose logs.
    private static final boolean VERBOSE_LOGS = false;

    // If we cleanup the ImageReaders on memory pressure it breaks VirtualDisplay
    // backed platform views. Disable for now as this is only necessary to work
    // around a Samsung-specific Android 14 bug.
    private static final boolean CLEANUP_ON_MEMORY_PRESSURE = false;

    private final long id;

    private boolean released;
    // Will be true in tests and on Android API < 33.
    private boolean ignoringFence = false;

    // The requested width and height are updated by setSize.
    private int requestedWidth = 1;
    private int requestedHeight = 1;
    // Whenever the requested width and height change we set this to be true so we
    // create a new ImageReader (inside getSurface) with the correct width and height.
    // We use this flag so that we lazily create the ImageReader only when a frame
    // will be produced at that size.
    private boolean createNewReader = true;

    // State held to track latency of various stages.
    private long lastDequeueTime = 0;
    private long lastQueueTime = 0;
    private long lastScheduleTime = 0;

    private Object lock = new Object();
    // REQUIRED: The following fields must only be accessed when lock is held.
    private final LinkedList<PerImageReader> imageReaderQueue = new LinkedList<PerImageReader>();
    private final HashMap<ImageReader, PerImageReader> perImageReaders =
        new HashMap<ImageReader, PerImageReader>();
    private PerImage lastDequeuedImage = null;
    private PerImageReader lastReaderDequeuedFrom = null;

    /** Internal class: state held per Image produced by ImageReaders. */
    private class PerImage {
      public final Image image;
      public final long queuedTime;

      public PerImage(Image image, long queuedTime) {
        this.image = image;
        this.queuedTime = queuedTime;
      }
    }

    /** Internal class: state held per ImageReader. */
    private class PerImageReader {
      public final ImageReader reader;
      private final LinkedList<PerImage> imageQueue = new LinkedList<PerImage>();
      private boolean closed = false;

      private final ImageReader.OnImageAvailableListener onImageAvailableListener =
          reader -> {
            Image image = null;
            try {
              image = reader.acquireLatestImage();
            } catch (IllegalStateException e) {
              Log.e(TAG, "onImageAvailable acquireLatestImage failed: " + e);
            }
            if (image == null) {
              return;
            }
            if (released || closed) {
              image.close();
              return;
            }
            onImage(reader, image);
          };

      public PerImageReader(ImageReader reader) {
        this.reader = reader;
        reader.setOnImageAvailableListener(onImageAvailableListener, new Handler());
      }

      PerImage queueImage(Image image) {
        if (closed) {
          return null;
        }
        PerImage perImage = new PerImage(image, System.nanoTime());
        imageQueue.add(perImage);
        // If we fall too far behind we will skip some frames.
        while (imageQueue.size() > 2) {
          PerImage r = imageQueue.removeFirst();
          if (VERBOSE_LOGS) {
            Log.i(TAG, "" + reader.hashCode() + " force closed image=" + r.image.hashCode());
          }
          r.image.close();
        }
        return perImage;
      }

      PerImage dequeueImage() {
        if (imageQueue.size() == 0) {
          return null;
        }
        PerImage r = imageQueue.removeFirst();
        return r;
      }

      /** returns true if we can prune this reader */
      boolean canPrune() {
        return imageQueue.size() == 0 && lastReaderDequeuedFrom != this;
      }

      void close() {
        closed = true;
        if (VERBOSE_LOGS) {
          Log.i(TAG, "Closing reader=" + reader.hashCode());
        }
        reader.close();
        imageQueue.clear();
      }
    }

    double deltaMillis(long deltaNanos) {
      double ms = (double) deltaNanos / (double) 1000000.0;
      return ms;
    }

    PerImageReader getOrCreatePerImageReader(ImageReader reader) {
      PerImageReader r = perImageReaders.get(reader);
      if (r == null) {
        r = new PerImageReader(reader);
        perImageReaders.put(reader, r);
        imageReaderQueue.add(r);
        if (VERBOSE_LOGS) {
          Log.i(TAG, "imageReaderQueue#=" + imageReaderQueue.size());
        }
      }
      return r;
    }

    void pruneImageReaderQueue() {
      boolean change = false;
      // Prune nodes from the head of the ImageReader queue.
      while (imageReaderQueue.size() > 1) {
        PerImageReader r = imageReaderQueue.peekFirst();
        if (!r.canPrune()) {
          // No more ImageReaders can be pruned this round.
          break;
        }
        imageReaderQueue.removeFirst();
        perImageReaders.remove(r.reader);
        r.close();
        change = true;
      }
      if (change && VERBOSE_LOGS) {
        Log.i(TAG, "Pruned image reader queue length=" + imageReaderQueue.size());
      }
    }

    void onImage(ImageReader reader, Image image) {
      PerImage queuedImage = null;
      synchronized (lock) {
        PerImageReader perReader = getOrCreatePerImageReader(reader);
        queuedImage = perReader.queueImage(image);
      }
      if (queuedImage == null) {
        // We got a late image.
        return;
      }
      if (VERBOSE_LOGS) {
        if (lastQueueTime != 0) {
          long now = System.nanoTime();
          long queueDelta = now - lastQueueTime;
          Log.i(
              TAG,
              ""
                  + reader.hashCode()
                  + " enqueued image="
                  + queuedImage.image.hashCode()
                  + " queueDelta="
                  + deltaMillis(queueDelta));
          lastQueueTime = now;
        } else {
          lastQueueTime = System.nanoTime();
        }
      }
      scheduleEngineFrame();
    }

    PerImage dequeueImage() {
      PerImage r = null;
      synchronized (lock) {
        for (PerImageReader reader : imageReaderQueue) {
          r = reader.dequeueImage();
          if (r == null) {
            // This reader is probably about to get pruned.
            continue;
          }
          if (VERBOSE_LOGS) {
            if (lastDequeueTime != 0) {
              long now = System.nanoTime();
              long dequeueDelta = now - lastDequeueTime;
              long queuedFor = now - r.queuedTime;
              long scheduleDelay = now - lastScheduleTime;
              Log.i(
                  TAG,
                  ""
                      + reader.reader.hashCode()
                      + " dequeued image="
                      + r.image.hashCode()
                      + " queuedFor= "
                      + deltaMillis(queuedFor)
                      + " dequeueDelta="
                      + deltaMillis(dequeueDelta)
                      + " scheduleDelay="
                      + deltaMillis(scheduleDelay));
              lastDequeueTime = now;
            } else {
              lastDequeueTime = System.nanoTime();
            }
          }
          if (lastDequeuedImage != null) {
            if (VERBOSE_LOGS) {
              Log.i(
                  TAG,
                  ""
                      + lastReaderDequeuedFrom.reader.hashCode()
                      + " closing image="
                      + lastDequeuedImage.image.hashCode());
            }
            // We must keep the last image dequeued open until we are done presenting
            // it. We have just dequeued a new image (r). Close the previously dequeued
            // image.
            lastDequeuedImage.image.close();
            lastDequeuedImage = null;
          }
          // Remember the last image and reader dequeued from. We do this because we must
          // keep both of these alive until we are done presenting the image.
          lastDequeuedImage = r;
          lastReaderDequeuedFrom = reader;
          break;
        }
        pruneImageReaderQueue();
      }
      return r;
    }

    @Override
    public void onTrimMemory(int level) {
      if (!CLEANUP_ON_MEMORY_PRESSURE) {
        return;
      }
      cleanup();
      createNewReader = true;
    }

    private void releaseInternal() {
      cleanup();
      released = true;
    }

    private void cleanup() {
      synchronized (lock) {
        for (PerImageReader pir : perImageReaders.values()) {
          if (lastReaderDequeuedFrom == pir) {
            lastReaderDequeuedFrom = null;
          }
          pir.close();
        }
        perImageReaders.clear();
        if (lastDequeuedImage != null) {
          lastDequeuedImage.image.close();
          lastDequeuedImage = null;
        }
        if (lastReaderDequeuedFrom != null) {
          lastReaderDequeuedFrom.close();
          lastReaderDequeuedFrom = null;
        }
        imageReaderQueue.clear();
      }
    }

    @TargetApi(API_LEVELS.API_33)
    private void waitOnFence(Image image) {
      try {
        SyncFence fence = image.getFence();
        fence.awaitForever();
      } catch (IOException e) {
        // Drop.
      }
    }

    private void maybeWaitOnFence(Image image) {
      if (image == null) {
        return;
      }
      if (ignoringFence) {
        return;
      }
      if (Build.VERSION.SDK_INT >= API_LEVELS.API_33) {
        // The fence API is only available on Android >= 33.
        waitOnFence(image);
        return;
      }
      // Log once per ImageTextureEntry.
      ignoringFence = true;
      Log.w(TAG, "ImageTextureEntry can't wait on the fence on Android < 33");
    }

    ImageReaderSurfaceProducer(long id) {
      this.id = id;
    }

    @Override
    public long id() {
      return id;
    }

    @Override
    public void release() {
      if (released) {
        return;
      }
      releaseInternal();
      unregisterTexture(id);
    }

    @Override
    public void setSize(int width, int height) {
      // Clamp to a minimum of 1. A 0x0 texture is a runtime exception in ImageReader.
      width = Math.max(1, width);
      height = Math.max(1, height);

      if (requestedWidth == width && requestedHeight == height) {
        // No size change.
        return;
      }
      this.createNewReader = true;
      this.requestedHeight = height;
      this.requestedWidth = width;
    }

    @Override
    public int getWidth() {
      return this.requestedWidth;
    }

    @Override
    public int getHeight() {
      return this.requestedHeight;
    }

    @Override
    public Surface getSurface() {
      PerImageReader pir = getActiveReader();
      if (VERBOSE_LOGS) {
        Log.i(TAG, "" + pir.reader.hashCode() + " returning surface to render a new frame.");
      }
      return pir.reader.getSurface();
    }

    @Override
    public void scheduleFrame() {
      if (VERBOSE_LOGS) {
        long now = System.nanoTime();
        if (lastScheduleTime != 0) {
          long delta = now - lastScheduleTime;
          Log.v(TAG, "scheduleFrame delta=" + deltaMillis(delta));
        }
        lastScheduleTime = now;
      }
      scheduleEngineFrame();
    }

    @Override
    @TargetApi(API_LEVELS.API_29)
    public Image acquireLatestImage() {
      PerImage r = dequeueImage();
      if (r == null) {
        return null;
      }
      maybeWaitOnFence(r.image);
      return r.image;
    }

    private PerImageReader getActiveReader() {
      synchronized (lock) {
        if (createNewReader) {
          createNewReader = false;
          // Create a new ImageReader and add it to the queue.
          ImageReader reader = createImageReader();
          if (VERBOSE_LOGS) {
            Log.i(
                TAG,
                "" + reader.hashCode() + " created w=" + requestedWidth + " h=" + requestedHeight);
          }
          return getOrCreatePerImageReader(reader);
        }
        return imageReaderQueue.peekLast();
      }
    }

    @Override
    protected void finalize() throws Throwable {
      try {
        if (released) {
          return;
        }
        releaseInternal();
        handler.post(new TextureFinalizerRunnable(id, flutterJNI));
      } finally {
        super.finalize();
      }
    }

    @TargetApi(API_LEVELS.API_33)
    private ImageReader createImageReader33() {
      final ImageReader.Builder builder = new ImageReader.Builder(requestedWidth, requestedHeight);
      // Allow for double buffering.
      builder.setMaxImages(MAX_IMAGES);
      // Use PRIVATE image format so that we can support video decoding.
      // TODO(johnmccutchan): Should we always use PRIVATE here? It may impact our ability to
      // read back texture data. If we don't always want to use it, how do we decide when to
      // use it or not? Perhaps PlatformViews can indicate if they may contain DRM'd content.
      // I need to investigate how PRIVATE impacts our ability to take screenshots or capture
      // the output of Flutter application.
      builder.setImageFormat(ImageFormat.PRIVATE);
      // Hint that consumed images will only be read by GPU.
      builder.setUsage(HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE);
      final ImageReader reader = builder.build();
      return reader;
    }

    @TargetApi(API_LEVELS.API_29)
    private ImageReader createImageReader29() {
      final ImageReader reader =
          ImageReader.newInstance(
              requestedWidth,
              requestedHeight,
              ImageFormat.PRIVATE,
              MAX_IMAGES,
              HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE);
      return reader;
    }

    private ImageReader createImageReader() {
      if (Build.VERSION.SDK_INT >= API_LEVELS.API_33) {
        return createImageReader33();
      } else if (Build.VERSION.SDK_INT >= API_LEVELS.API_29) {
        return createImageReader29();
      }
      throw new UnsupportedOperationException(
          "ImageReaderPlatformViewRenderTarget requires API version 29+");
    }

    @VisibleForTesting
    public void disableFenceForTest() {
      // Roboelectric's implementation of SyncFence is borked.
      ignoringFence = true;
    }

    @VisibleForTesting
    public int numImageReaders() {
      synchronized (lock) {
        return imageReaderQueue.size();
      }
    }

    @VisibleForTesting
    public int numImages() {
      int r = 0;
      synchronized (lock) {
        for (PerImageReader reader : imageReaderQueue) {
          r += reader.imageQueue.size();
        }
      }
      return r;
    }
  }

  @Keep
  final class ImageTextureRegistryEntry
      implements TextureRegistry.ImageTextureEntry, TextureRegistry.ImageConsumer {
    private static final String TAG = "ImageTextureRegistryEntry";
    private final long id;
    private boolean released;
    private boolean ignoringFence = false;
    private Image image;

    ImageTextureRegistryEntry(long id) {
      this.id = id;
    }

    @Override
    public long id() {
      return id;
    }

    @Override
    public void release() {
      if (released) {
        return;
      }
      released = true;
      if (image != null) {
        image.close();
        image = null;
      }
      unregisterTexture(id);
    }

    @Override
    public void pushImage(Image image) {
      if (released) {
        return;
      }
      Image toClose;
      synchronized (this) {
        toClose = this.image;
        this.image = image;
      }
      // Close the previously pushed buffer.
      if (toClose != null) {
        Log.e(TAG, "Dropping PlatformView Frame");
        toClose.close();
      }
      if (image != null) {
        scheduleEngineFrame();
      }
    }

    @TargetApi(API_LEVELS.API_33)
    private void waitOnFence(Image image) {
      try {
        SyncFence fence = image.getFence();
        fence.awaitForever();
      } catch (IOException e) {
        // Drop.
      }
    }

    @TargetApi(API_LEVELS.API_29)
    private void maybeWaitOnFence(Image image) {
      if (image == null) {
        return;
      }
      if (ignoringFence) {
        return;
      }
      if (Build.VERSION.SDK_INT >= API_LEVELS.API_33) {
        // The fence API is only available on Android >= 33.
        waitOnFence(image);
        return;
      }
      // Log once per ImageTextureEntry.
      ignoringFence = true;
      Log.w(TAG, "ImageTextureEntry can't wait on the fence on Android < 33");
    }

    @Override
    @TargetApi(API_LEVELS.API_29)
    public Image acquireLatestImage() {
      Image r;
      synchronized (this) {
        r = this.image;
        this.image = null;
      }
      maybeWaitOnFence(r);
      return r;
    }

    @Override
    protected void finalize() throws Throwable {
      try {
        if (released) {
          return;
        }
        if (image != null) {
          // Be sure to finalize any cached image.
          image.close();
          image = null;
        }
        released = true;
        handler.post(new TextureFinalizerRunnable(id, flutterJNI));
      } finally {
        super.finalize();
      }
    }
  }
  // ------ END TextureRegistry IMPLEMENTATION ----

  /**
   * Notifies Flutter that the given {@code surface} was created and is available for Flutter
   * rendering.
   *
   * <p>If called more than once, the current native resources are released. This can be undesired
   * if the Engine expects to reuse this surface later. For example, this is true when platform
   * views are displayed in a frame, and then removed in the next frame.
   *
   * <p>To avoid releasing the current surface resources, set {@code keepCurrentSurface} to true.
   *
   * <p>See {@link android.view.SurfaceHolder.Callback} and {@link
   * android.view.TextureView.SurfaceTextureListener}
   *
   * @param surface The render surface.
   * @param onlySwap True if the current active surface should not be detached.
   */
  public void startRenderingToSurface(@NonNull Surface surface, boolean onlySwap) {
    if (!onlySwap) {
      // Stop rendering to the surface releases the associated native resources, which causes
      // a glitch when toggling between rendering to an image view (hybrid composition) and
      // rendering directly to a Surface or Texture view. For more,
      // https://github.com/flutter/flutter/issues/95343
      stopRenderingToSurface();
    }

    this.surface = surface;

    if (onlySwap) {
      // In the swap case we are just swapping the surface that we render to.
      flutterJNI.onSurfaceWindowChanged(surface);
    } else {
      // In the non-swap case we are creating a new surface to render to.
      flutterJNI.onSurfaceCreated(surface);
    }
  }

  /**
   * Swaps the {@link Surface} used to render the current frame.
   *
   * <p>In hybrid composition, the root surfaces changes from {@link
   * android.view.SurfaceHolder#getSurface()} to {@link android.media.ImageReader#getSurface()} when
   * a platform view is in the current frame.
   */
  public void swapSurface(@NonNull Surface surface) {
    this.surface = surface;
    flutterJNI.onSurfaceWindowChanged(surface);
  }

  /**
   * Notifies Flutter that a {@code surface} previously registered with {@link
   * #startRenderingToSurface(Surface, boolean)} has changed size to the given {@code width} and
   * {@code height}.
   *
   * <p>See {@link android.view.SurfaceHolder.Callback} and {@link
   * android.view.TextureView.SurfaceTextureListener}
   */
  public void surfaceChanged(int width, int height) {
    flutterJNI.onSurfaceChanged(width, height);
  }

  /**
   * Notifies Flutter that a {@code surface} previously registered with {@link
   * #startRenderingToSurface(Surface, boolean)} has been destroyed and needs to be released and
   * cleaned up on the Flutter side.
   *
   * <p>See {@link android.view.SurfaceHolder.Callback} and {@link
   * android.view.TextureView.SurfaceTextureListener}
   */
  public void stopRenderingToSurface() {
    if (surface != null) {
      flutterJNI.onSurfaceDestroyed();

      // TODO(mattcarroll): the source of truth for this call should be FlutterJNI, which is
      // where the call to onFlutterUiDisplayed() comes from. However, no such native callback
      // exists yet, so until the engine and FlutterJNI are configured to call us back when
      // rendering stops, we will manually monitor that change here.
      if (isDisplayingFlutterUi) {
        flutterUiDisplayListener.onFlutterUiNoLongerDisplayed();
      }

      isDisplayingFlutterUi = false;
      surface = null;
    }
  }

  /**
   * Notifies Flutter that the viewport metrics, e.g. window height and width, have changed.
   *
   * <p>If the width, height, or devicePixelRatio are less than or equal to 0, this update is
   * ignored.
   *
   * @param viewportMetrics The metrics to send to the Dart application.
   */
  public void setViewportMetrics(@NonNull ViewportMetrics viewportMetrics) {
    // We might get called with just the DPR if width/height aren't available yet.
    // Just ignore, as it will get called again when width/height are set.
    if (!viewportMetrics.validate()) {
      return;
    }
    Log.v(
        TAG,
        "Setting viewport metrics\n"
            + "Size: "
            + viewportMetrics.width
            + " x "
            + viewportMetrics.height
            + "\n"
            + "Padding - L: "
            + viewportMetrics.viewPaddingLeft
            + ", T: "
            + viewportMetrics.viewPaddingTop
            + ", R: "
            + viewportMetrics.viewPaddingRight
            + ", B: "
            + viewportMetrics.viewPaddingBottom
            + "\n"
            + "Insets - L: "
            + viewportMetrics.viewInsetLeft
            + ", T: "
            + viewportMetrics.viewInsetTop
            + ", R: "
            + viewportMetrics.viewInsetRight
            + ", B: "
            + viewportMetrics.viewInsetBottom
            + "\n"
            + "System Gesture Insets - L: "
            + viewportMetrics.systemGestureInsetLeft
            + ", T: "
            + viewportMetrics.systemGestureInsetTop
            + ", R: "
            + viewportMetrics.systemGestureInsetRight
            + ", B: "
            + viewportMetrics.systemGestureInsetRight
            + "\n"
            + "Display Features: "
            + viewportMetrics.displayFeatures.size());

    int[] displayFeaturesBounds = new int[viewportMetrics.displayFeatures.size() * 4];
    int[] displayFeaturesType = new int[viewportMetrics.displayFeatures.size()];
    int[] displayFeaturesState = new int[viewportMetrics.displayFeatures.size()];
    for (int i = 0; i < viewportMetrics.displayFeatures.size(); i++) {
      DisplayFeature displayFeature = viewportMetrics.displayFeatures.get(i);
      displayFeaturesBounds[4 * i] = displayFeature.bounds.left;
      displayFeaturesBounds[4 * i + 1] = displayFeature.bounds.top;
      displayFeaturesBounds[4 * i + 2] = displayFeature.bounds.right;
      displayFeaturesBounds[4 * i + 3] = displayFeature.bounds.bottom;
      displayFeaturesType[i] = displayFeature.type.encodedValue;
      displayFeaturesState[i] = displayFeature.state.encodedValue;
    }

    flutterJNI.setViewportMetrics(
        viewportMetrics.devicePixelRatio,
        viewportMetrics.width,
        viewportMetrics.height,
        viewportMetrics.viewPaddingTop,
        viewportMetrics.viewPaddingRight,
        viewportMetrics.viewPaddingBottom,
        viewportMetrics.viewPaddingLeft,
        viewportMetrics.viewInsetTop,
        viewportMetrics.viewInsetRight,
        viewportMetrics.viewInsetBottom,
        viewportMetrics.viewInsetLeft,
        viewportMetrics.systemGestureInsetTop,
        viewportMetrics.systemGestureInsetRight,
        viewportMetrics.systemGestureInsetBottom,
        viewportMetrics.systemGestureInsetLeft,
        viewportMetrics.physicalTouchSlop,
        displayFeaturesBounds,
        displayFeaturesType,
        displayFeaturesState);
  }

  // TODO(mattcarroll): describe the native behavior that this invokes
  // TODO(mattcarroll): determine if this is nullable or nonnull
  public Bitmap getBitmap() {
    return flutterJNI.getBitmap();
  }

  // TODO(mattcarroll): describe the native behavior that this invokes
  public void dispatchPointerDataPacket(@NonNull ByteBuffer buffer, int position) {
    flutterJNI.dispatchPointerDataPacket(buffer, position);
  }

  // TODO(mattcarroll): describe the native behavior that this invokes
  private void registerTexture(long textureId, @NonNull SurfaceTextureWrapper textureWrapper) {
    flutterJNI.registerTexture(textureId, textureWrapper);
  }

  private void registerImageTexture(
      long textureId, @NonNull TextureRegistry.ImageConsumer imageTexture) {
    flutterJNI.registerImageTexture(textureId, imageTexture);
  }

  private void scheduleEngineFrame() {
    flutterJNI.scheduleFrame();
  }

  // TODO(mattcarroll): describe the native behavior that this invokes
  private void markTextureFrameAvailable(long textureId) {
    flutterJNI.markTextureFrameAvailable(textureId);
  }

  // TODO(mattcarroll): describe the native behavior that this invokes
  private void unregisterTexture(long textureId) {
    flutterJNI.unregisterTexture(textureId);
  }

  // TODO(mattcarroll): describe the native behavior that this invokes
  public boolean isSoftwareRenderingEnabled() {
    return flutterJNI.getIsSoftwareRenderingEnabled();
  }

  // TODO(mattcarroll): describe the native behavior that this invokes
  public void setAccessibilityFeatures(int flags) {
    flutterJNI.setAccessibilityFeatures(flags);
  }

  // TODO(mattcarroll): describe the native behavior that this invokes
  public void setSemanticsEnabled(boolean enabled) {
    flutterJNI.setSemanticsEnabled(enabled);
  }

  // TODO(mattcarroll): describe the native behavior that this invokes
  public void dispatchSemanticsAction(
      int nodeId, int action, @Nullable ByteBuffer args, int argsPosition) {
    flutterJNI.dispatchSemanticsAction(nodeId, action, args, argsPosition);
  }

  /**
   * Mutable data structure that holds all viewport metrics properties that Flutter cares about.
   *
   * <p>All distance measurements, e.g., width, height, padding, viewInsets, are measured in device
   * pixels, not logical pixels.
   */
  public static final class ViewportMetrics {
    /** A value that indicates the setting has not been set. */
    public static final int unsetValue = -1;

    public float devicePixelRatio = 1.0f;
    public int width = 0;
    public int height = 0;
    public int viewPaddingTop = 0;
    public int viewPaddingRight = 0;
    public int viewPaddingBottom = 0;
    public int viewPaddingLeft = 0;
    public int viewInsetTop = 0;
    public int viewInsetRight = 0;
    public int viewInsetBottom = 0;
    public int viewInsetLeft = 0;
    public int systemGestureInsetTop = 0;
    public int systemGestureInsetRight = 0;
    public int systemGestureInsetBottom = 0;
    public int systemGestureInsetLeft = 0;
    public int physicalTouchSlop = unsetValue;

    /**
     * Whether this instance contains valid metrics for the Flutter application.
     *
     * @return True if width, height, and devicePixelRatio are > 0; false otherwise.
     */
    boolean validate() {
      return width > 0 && height > 0 && devicePixelRatio > 0;
    }

    public List<DisplayFeature> displayFeatures = new ArrayList<>();
  }

  /**
   * Description of a physical feature on the display.
   *
   * <p>A display feature is a distinctive physical attribute located within the display panel of
   * the device. It can intrude into the application window space and create a visual distortion,
   * visual or touch discontinuity, make some area invisible or create a logical divider or
   * separation in the screen space.
   *
   * <p>Based on {@link androidx.window.layout.DisplayFeature}, with added support for cutouts.
   */
  public static final class DisplayFeature {
    public final Rect bounds;
    public final DisplayFeatureType type;
    public final DisplayFeatureState state;

    public DisplayFeature(Rect bounds, DisplayFeatureType type, DisplayFeatureState state) {
      this.bounds = bounds;
      this.type = type;
      this.state = state;
    }

    public DisplayFeature(Rect bounds, DisplayFeatureType type) {
      this.bounds = bounds;
      this.type = type;
      this.state = DisplayFeatureState.UNKNOWN;
    }
  }

  /**
   * Types of display features that can appear on the viewport.
   *
   * <p>Some, like {@link #FOLD}, can be reported without actually occluding the screen. They are
   * useful for knowing where the display is bent or has a crease. The {@link DisplayFeature#bounds}
   * can be 0-width in such cases.
   */
  public enum DisplayFeatureType {
    /**
     * Type of display feature not yet known to Flutter. This can happen if WindowManager is updated
     * with new types. The {@link DisplayFeature#bounds} is the only known property.
     */
    UNKNOWN(0),

    /**
     * A fold in the flexible display that does not occlude the screen. Corresponds to {@link
     * androidx.window.layout.FoldingFeature.OcclusionType#NONE}
     */
    FOLD(1),

    /**
     * Splits the display in two separate panels that can fold. Occludes the screen. Corresponds to
     * {@link androidx.window.layout.FoldingFeature.OcclusionType#FULL}
     */
    HINGE(2),

    /**
     * Area of the screen that usually houses cameras or sensors. Occludes the screen. Corresponds
     * to {@link android.view.DisplayCutout}
     */
    CUTOUT(3);

    public final int encodedValue;

    DisplayFeatureType(int encodedValue) {
      this.encodedValue = encodedValue;
    }
  }

  /**
   * State of the display feature.
   *
   * <p>For foldables, the state is the posture. For cutouts, this property is {@link #UNKNOWN}
   */
  public enum DisplayFeatureState {
    /** The display feature is a cutout or this state is new and not yet known to Flutter. */
    UNKNOWN(0),

    /**
     * The foldable device is completely open. The screen space that is presented to the user is
     * flat. Corresponds to {@link androidx.window.layout.FoldingFeature.State#FLAT}
     */
    POSTURE_FLAT(1),

    /**
     * The foldable device's hinge is in an intermediate position between opened and closed state.
     * There is a non-flat angle between parts of the flexible screen or between physical display
     * panels. Corresponds to {@link androidx.window.layout.FoldingFeature.State#HALF_OPENED}
     */
    POSTURE_HALF_OPENED(2);

    public final int encodedValue;

    DisplayFeatureState(int encodedValue) {
      this.encodedValue = encodedValue;
    }
  }
}
