// 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.plugin.platform;

import static android.view.MotionEvent.PointerCoords;
import static android.view.MotionEvent.PointerProperties;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.MutableContextWrapper;
import android.os.Build;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.annotation.VisibleForTesting;
import io.flutter.Log;
import io.flutter.embedding.android.AndroidTouchProcessor;
import io.flutter.embedding.android.FlutterView;
import io.flutter.embedding.android.MotionEventTracker;
import io.flutter.embedding.engine.FlutterOverlaySurface;
import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.embedding.engine.mutatorsstack.*;
import io.flutter.embedding.engine.renderer.FlutterRenderer;
import io.flutter.embedding.engine.systemchannels.PlatformViewsChannel;
import io.flutter.plugin.editing.TextInputPlugin;
import io.flutter.util.ViewUtils;
import io.flutter.view.AccessibilityBridge;
import io.flutter.view.TextureRegistry;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

/**
 * Manages platform views.
 *
 * <p>Each {@link io.flutter.embedding.engine.FlutterEngine} or {@link
 * io.flutter.app.FlutterPluginRegistry} has a single platform views controller. A platform views
 * controller can be attached to at most one Flutter view.
 */
public class PlatformViewsController implements PlatformViewsAccessibilityDelegate {
  private static final String TAG = "PlatformViewsController";

  // These view types allow out-of-band drawing commands that don't notify the Android view
  // hierarchy.
  // To support these cases, Flutter hosts the embedded view in a VirtualDisplay,
  // and binds the VirtualDisplay to a GL texture that is then composed by the engine.
  // However, there are a few issues with Virtual Displays. For example, they don't fully support
  // accessibility due to https://github.com/flutter/flutter/issues/29717,
  // and keyboard interactions may have non-deterministic behavior.
  // Views that issue out-of-band drawing commands that aren't included in this array are
  // required to call `View#invalidate()` to notify Flutter about the update.
  // This isn't ideal, but given all the other limitations it's a reasonable tradeoff.
  // Related issue: https://github.com/flutter/flutter/issues/103630
  private static Class[] VIEW_TYPES_REQUIRE_VIRTUAL_DISPLAY = {SurfaceView.class};

  private final PlatformViewRegistryImpl registry;

  private AndroidTouchProcessor androidTouchProcessor;

  // The context of the Activity or Fragment hosting the render target for the Flutter engine.
  private Context context;

  // The View currently rendering the Flutter UI associated with these platform views.
  private FlutterView flutterView;

  // The texture registry maintaining the textures into which the embedded views will be rendered.
  @Nullable private TextureRegistry textureRegistry;

  @Nullable private TextInputPlugin textInputPlugin;

  // The system channel used to communicate with the framework about platform views.
  private PlatformViewsChannel platformViewsChannel;

  // The accessibility bridge to which accessibility events form the platform views will be
  // dispatched.
  private final AccessibilityEventsDelegate accessibilityEventsDelegate;

  // TODO(mattcarroll): Refactor overall platform views to facilitate testing and then make
  // this private. This is visible as a hack to facilitate testing. This was deemed the least
  // bad option at the time of writing.
  @VisibleForTesting /* package */ final HashMap<Integer, VirtualDisplayController> vdControllers;

  // Maps a virtual display's context to the embedded view hosted in this virtual display.
  // Since each virtual display has it's unique context this allows associating any view with the
  // platform view that
  // it is associated with(e.g if a platform view creates other views in the same virtual display.
  @VisibleForTesting /* package */ final HashMap<Context, View> contextToEmbeddedView;

  // The platform views.
  private final SparseArray<PlatformView> platformViews;

  // The platform view wrappers that are appended to FlutterView.
  //
  // These platform views use a PlatformViewLayer in the framework. This is different than
  // the platform views that use a TextureLayer.
  //
  // This distinction is necessary because a PlatformViewLayer allows to embed Android's
  // SurfaceViews in a Flutter app whereas the texture layer is unable to support such native views.
  //
  // If an entry in `platformViews` doesn't have an entry in this array, the platform view isn't
  // in the view hierarchy.
  //
  // This view provides a wrapper that applies scene builder operations to the platform view.
  // For example, a transform matrix, or setting opacity on the platform view layer.
  private final SparseArray<FlutterMutatorView> platformViewParent;

  // Map of unique IDs to views that render overlay layers.
  private final SparseArray<PlatformOverlayView> overlayLayerViews;

  // The platform view wrappers that are appended to FlutterView.
  //
  // These platform views use a TextureLayer in the framework. This is different than
  // the platform views that use a PlatformViewLayer.
  //
  // This is the default mode, and recommended for better performance.
  private final SparseArray<PlatformViewWrapper> viewWrappers;

  // Next available unique ID for use in overlayLayerViews.
  private int nextOverlayLayerId = 0;

  // Tracks whether the flutterView has been converted to use a FlutterImageView.
  private boolean flutterViewConvertedToImageView = false;

  // When adding platform views using Hybrid Composition, the engine converts the render surface
  // to a FlutterImageView to help improve animation synchronization on Android. This flag allows
  // disabling this conversion through the PlatformView platform channel.
  private boolean synchronizeToNativeViewHierarchy = true;

  // Overlay layer IDs that were displayed since the start of the current frame.
  private final HashSet<Integer> currentFrameUsedOverlayLayerIds;

  // Platform view IDs that were displayed since the start of the current frame.
  private final HashSet<Integer> currentFrameUsedPlatformViewIds;

  // Used to acquire the original motion events using the motionEventIds.
  private final MotionEventTracker motionEventTracker;

  // Whether software rendering is used.
  private boolean usesSoftwareRendering = false;

  private final PlatformViewsChannel.PlatformViewsHandler channelHandler =
      new PlatformViewsChannel.PlatformViewsHandler() {

        @TargetApi(19)
        @Override
        // TODO(egarciad): Remove the need for this.
        // https://github.com/flutter/flutter/issues/96679
        public void createForPlatformViewLayer(
            @NonNull PlatformViewsChannel.PlatformViewCreationRequest request) {
          // API level 19 is required for `android.graphics.ImageReader`.
          ensureValidAndroidVersion(19);
          ensureValidRequest(request);

          final PlatformView platformView = createPlatformView(request, false);

          configureForHybridComposition(platformView, request);
          // New code should be added to configureForHybridComposition, not here, unless it is
          // not applicable to fallback from TLHC to HC.
        }

        @TargetApi(20)
        @Override
        public long createForTextureLayer(
            @NonNull PlatformViewsChannel.PlatformViewCreationRequest request) {
          ensureValidRequest(request);
          final int viewId = request.viewId;
          if (viewWrappers.get(viewId) != null) {
            throw new IllegalStateException(
                "Trying to create an already created platform view, view id: " + viewId);
          }
          if (textureRegistry == null) {
            throw new IllegalStateException(
                "Texture registry is null. This means that platform views controller was detached, view id: "
                    + viewId);
          }
          if (flutterView == null) {
            throw new IllegalStateException(
                "Flutter view is null. This means the platform views controller doesn't have an attached view, view id: "
                    + viewId);
          }

          final PlatformView platformView = createPlatformView(request, true);

          final View embeddedView = platformView.getView();
          if (embeddedView.getParent() != null) {
            throw new IllegalStateException(
                "The Android view returned from PlatformView#getView() was already added to a parent view.");
          }

          // The newer Texture Layer Hybrid Composition mode isn't suppported if any of the
          // following are true:
          // - The embedded view contains any of the VIEW_TYPES_REQUIRE_VIRTUAL_DISPLAY view types.
          //   These views allow out-of-band graphics operations that aren't notified to the Android
          //   view hierarchy via callbacks such as ViewParent#onDescendantInvalidated().
          // - The API level is <23, due to TLHC implementation API requirements.
          final boolean supportsTextureLayerMode =
              Build.VERSION.SDK_INT >= 23
                  && !ViewUtils.hasChildViewOfType(
                      embeddedView, VIEW_TYPES_REQUIRE_VIRTUAL_DISPLAY);

          // Fall back to Hybrid Composition or Virtual Display when necessary, depending on which
          // fallback mode is requested.
          if (!supportsTextureLayerMode) {
            if (request.displayMode
                == PlatformViewsChannel.PlatformViewCreationRequest.RequestedDisplayMode
                    .TEXTURE_WITH_HYBRID_FALLBACK) {
              configureForHybridComposition(platformView, request);
              return PlatformViewsChannel.PlatformViewsHandler.NON_TEXTURE_FALLBACK;
            } else if (!usesSoftwareRendering) { // Virtual Display doesn't support software mode.
              return configureForVirtualDisplay(platformView, request);
            }
            // TODO(stuartmorgan): Consider throwing a specific exception here as a breaking change.
            // For now, preserve the 3.0 behavior of falling through to Texture Layer mode even
            // though it won't work correctly.
          }
          return configureForTextureLayerComposition(platformView, request);
        }

        @Override
        public void dispose(int viewId) {
          final PlatformView platformView = platformViews.get(viewId);
          if (platformView == null) {
            Log.e(TAG, "Disposing unknown platform view with id: " + viewId);
            return;
          }
          platformViews.remove(viewId);

          try {
            platformView.dispose();
          } catch (RuntimeException exception) {
            Log.e(TAG, "Disposing platform view threw an exception", exception);
          }

          if (usesVirtualDisplay(viewId)) {
            final VirtualDisplayController vdController = vdControllers.get(viewId);
            final View embeddedView = vdController.getView();
            if (embeddedView != null) {
              contextToEmbeddedView.remove(embeddedView.getContext());
            }
            vdControllers.remove(viewId);
            return;
          }
          // The platform view is displayed using a TextureLayer and is inserted in the view
          // hierarchy.
          final PlatformViewWrapper viewWrapper = viewWrappers.get(viewId);
          if (viewWrapper != null) {
            viewWrapper.removeAllViews();
            viewWrapper.release();
            viewWrapper.unsetOnDescendantFocusChangeListener();

            final ViewGroup wrapperParent = (ViewGroup) viewWrapper.getParent();
            if (wrapperParent != null) {
              wrapperParent.removeView(viewWrapper);
            }
            viewWrappers.remove(viewId);
            return;
          }
          // The platform view is displayed using a PlatformViewLayer.
          final FlutterMutatorView parentView = platformViewParent.get(viewId);
          if (parentView != null) {
            parentView.removeAllViews();
            parentView.unsetOnDescendantFocusChangeListener();

            final ViewGroup mutatorViewParent = (ViewGroup) parentView.getParent();
            if (mutatorViewParent != null) {
              mutatorViewParent.removeView(parentView);
            }
            platformViewParent.remove(viewId);
          }
        }

        @Override
        public void offset(int viewId, double top, double left) {
          if (usesVirtualDisplay(viewId)) {
            // Virtual displays don't need an accessibility offset.
            return;
          }
          // For platform views that use TextureView and are in the view hierarchy, set
          // an offset to the wrapper view.
          // This ensures that the accessibility highlights are drawn in the expected position on
          // screen.
          // This offset doesn't affect the position of the embeded view by itself since the GL
          // texture is positioned by the Flutter engine, which knows where to position different
          // types of layers.
          final PlatformViewWrapper viewWrapper = viewWrappers.get(viewId);
          if (viewWrapper == null) {
            Log.e(TAG, "Setting offset for unknown platform view with id: " + viewId);
            return;
          }
          final int physicalTop = toPhysicalPixels(top);
          final int physicalLeft = toPhysicalPixels(left);
          final FrameLayout.LayoutParams layoutParams =
              (FrameLayout.LayoutParams) viewWrapper.getLayoutParams();
          layoutParams.topMargin = physicalTop;
          layoutParams.leftMargin = physicalLeft;
          viewWrapper.setLayoutParams(layoutParams);
        }

        @Override
        public void resize(
            @NonNull PlatformViewsChannel.PlatformViewResizeRequest request,
            @NonNull PlatformViewsChannel.PlatformViewBufferResized onComplete) {
          final int physicalWidth = toPhysicalPixels(request.newLogicalWidth);
          final int physicalHeight = toPhysicalPixels(request.newLogicalHeight);
          final int viewId = request.viewId;

          if (usesVirtualDisplay(viewId)) {
            final float originalDisplayDensity = getDisplayDensity();
            final VirtualDisplayController vdController = vdControllers.get(viewId);
            // Resizing involved moving the platform view to a new virtual display. Doing so
            // potentially results in losing an active input connection. To make sure we preserve
            // the input connection when resizing we lock it here and unlock after the resize is
            // complete.
            lockInputConnection(vdController);
            vdController.resize(
                physicalWidth,
                physicalHeight,
                () -> {
                  unlockInputConnection(vdController);
                  // Converting back to logic pixels requires a context, which may no longer be
                  // available. If that happens, assume the same logic/physical relationship as
                  // was present when the request arrived.
                  final float displayDensity =
                      context == null ? originalDisplayDensity : getDisplayDensity();
                  onComplete.run(
                      new PlatformViewsChannel.PlatformViewBufferSize(
                          toLogicalPixels(vdController.getBufferWidth(), displayDensity),
                          toLogicalPixels(vdController.getBufferHeight(), displayDensity)));
                });
            return;
          }

          final PlatformView platformView = platformViews.get(viewId);
          final PlatformViewWrapper viewWrapper = viewWrappers.get(viewId);
          if (platformView == null || viewWrapper == null) {
            Log.e(TAG, "Resizing unknown platform view with id: " + viewId);
            return;
          }
          // Resize the buffer only when the current buffer size is smaller than the new size.
          // This is required to prevent a situation when smooth keyboard animation
          // resizes the texture too often, such that the GPU and the platform thread don't agree on
          // the
          // timing of the new size.
          // Resizing the texture causes pixel stretching since the size of the GL texture used in
          // the engine
          // is set by the framework, but the texture buffer size is set by the platform down below.
          if (physicalWidth > viewWrapper.getBufferWidth()
              || physicalHeight > viewWrapper.getBufferHeight()) {
            viewWrapper.setBufferSize(physicalWidth, physicalHeight);
          }

          final ViewGroup.LayoutParams viewWrapperLayoutParams = viewWrapper.getLayoutParams();
          viewWrapperLayoutParams.width = physicalWidth;
          viewWrapperLayoutParams.height = physicalHeight;
          viewWrapper.setLayoutParams(viewWrapperLayoutParams);

          final View embeddedView = platformView.getView();
          if (embeddedView != null) {
            final ViewGroup.LayoutParams embeddedViewLayoutParams = embeddedView.getLayoutParams();
            embeddedViewLayoutParams.width = physicalWidth;
            embeddedViewLayoutParams.height = physicalHeight;
            embeddedView.setLayoutParams(embeddedViewLayoutParams);
          }
          onComplete.run(
              new PlatformViewsChannel.PlatformViewBufferSize(
                  toLogicalPixels(viewWrapper.getBufferWidth()),
                  toLogicalPixels(viewWrapper.getBufferHeight())));
        }

        @Override
        public void onTouch(@NonNull PlatformViewsChannel.PlatformViewTouch touch) {
          final int viewId = touch.viewId;
          final float density = context.getResources().getDisplayMetrics().density;

          if (usesVirtualDisplay(viewId)) {
            final VirtualDisplayController vdController = vdControllers.get(viewId);
            final MotionEvent event = toMotionEvent(density, touch, true);
            vdController.dispatchTouchEvent(event);
            return;
          }

          final PlatformView platformView = platformViews.get(viewId);
          if (platformView == null) {
            Log.e(TAG, "Sending touch to an unknown view with id: " + viewId);
            return;
          }
          final View view = platformView.getView();
          if (view == null) {
            Log.e(TAG, "Sending touch to a null view with id: " + viewId);
            return;
          }
          final MotionEvent event = toMotionEvent(density, touch, false);
          view.dispatchTouchEvent(event);
        }

        @TargetApi(17)
        @Override
        public void setDirection(int viewId, int direction) {
          if (!validateDirection(direction)) {
            throw new IllegalStateException(
                "Trying to set unknown direction value: "
                    + direction
                    + "(view id: "
                    + viewId
                    + ")");
          }

          View embeddedView;

          if (usesVirtualDisplay(viewId)) {
            final VirtualDisplayController controller = vdControllers.get(viewId);
            embeddedView = controller.getView();
          } else {
            final PlatformView platformView = platformViews.get(viewId);
            if (platformView == null) {
              Log.e(TAG, "Setting direction to an unknown view with id: " + viewId);
              return;
            }
            embeddedView = platformView.getView();
          }
          if (embeddedView == null) {
            Log.e(TAG, "Setting direction to a null view with id: " + viewId);
            return;
          }
          embeddedView.setLayoutDirection(direction);
        }

        @Override
        public void clearFocus(int viewId) {
          View embeddedView;

          if (usesVirtualDisplay(viewId)) {
            final VirtualDisplayController controller = vdControllers.get(viewId);
            embeddedView = controller.getView();
          } else {
            final PlatformView platformView = platformViews.get(viewId);
            if (platformView == null) {
              Log.e(TAG, "Clearing focus on an unknown view with id: " + viewId);
              return;
            }
            embeddedView = platformView.getView();
          }
          if (embeddedView == null) {
            Log.e(TAG, "Clearing focus on a null view with id: " + viewId);
            return;
          }
          embeddedView.clearFocus();
        }

        private void ensureValidAndroidVersion(int minSdkVersion) {
          if (Build.VERSION.SDK_INT < minSdkVersion) {
            throw new IllegalStateException(
                "Trying to use platform views with API "
                    + Build.VERSION.SDK_INT
                    + ", required API level is: "
                    + minSdkVersion);
          }
        }

        private void ensureValidRequest(
            @NonNull PlatformViewsChannel.PlatformViewCreationRequest request) {
          if (!validateDirection(request.direction)) {
            throw new IllegalStateException(
                "Trying to create a view with unknown direction value: "
                    + request.direction
                    + "(view id: "
                    + request.viewId
                    + ")");
          }
        }

        // Creates a platform view based on `request`, performs configuration that's common to
        // all display modes, and adds it to `platformViews`.
        @TargetApi(19)
        private PlatformView createPlatformView(
            @NonNull PlatformViewsChannel.PlatformViewCreationRequest request,
            boolean wrapContext) {
          final PlatformViewFactory viewFactory = registry.getFactory(request.viewType);
          if (viewFactory == null) {
            throw new IllegalStateException(
                "Trying to create a platform view of unregistered type: " + request.viewType);
          }

          Object createParams = null;
          if (request.params != null) {
            createParams = viewFactory.getCreateArgsCodec().decodeMessage(request.params);
          }

          // In some display modes, the context needs to be modified during display.
          // TODO(stuartmorgan): Make this wrapping unconditional if possible; for context see
          // https://github.com/flutter/flutter/issues/113449
          final Context mutableContext = wrapContext ? new MutableContextWrapper(context) : context;
          final PlatformView platformView =
              viewFactory.create(mutableContext, request.viewId, createParams);

          // Configure the view to match the requested layout direction.
          final View embeddedView = platformView.getView();
          if (embeddedView == null) {
            throw new IllegalStateException(
                "PlatformView#getView() returned null, but an Android view reference was expected.");
          }
          embeddedView.setLayoutDirection(request.direction);

          platformViews.put(request.viewId, platformView);
          return platformView;
        }

        // Configures the view for Hybrid Composition mode.
        private void configureForHybridComposition(
            @NonNull PlatformView platformView,
            @NonNull PlatformViewsChannel.PlatformViewCreationRequest request) {
          Log.i(TAG, "Using hybrid composition for platform view: " + request.viewId);
        }

        // Configures the view for Virtual Display mode, returning the associated texture ID.
        private long configureForVirtualDisplay(
            @NonNull PlatformView platformView,
            @NonNull PlatformViewsChannel.PlatformViewCreationRequest request) {
          // This mode adds the view to a virtual display, which is wired up to a GL texture that
          // is composed by the Flutter engine.

          // API level 20 is required to use VirtualDisplay#setSurface.
          ensureValidAndroidVersion(20);

          Log.i(TAG, "Hosting view in a virtual display for platform view: " + request.viewId);

          final TextureRegistry.SurfaceTextureEntry textureEntry =
              textureRegistry.createSurfaceTexture();
          final int physicalWidth = toPhysicalPixels(request.logicalWidth);
          final int physicalHeight = toPhysicalPixels(request.logicalHeight);
          final VirtualDisplayController vdController =
              VirtualDisplayController.create(
                  context,
                  accessibilityEventsDelegate,
                  platformView,
                  textureEntry,
                  physicalWidth,
                  physicalHeight,
                  request.viewId,
                  null,
                  (view, hasFocus) -> {
                    if (hasFocus) {
                      platformViewsChannel.invokeViewFocused(request.viewId);
                    }
                  });

          if (vdController == null) {
            throw new IllegalStateException(
                "Failed creating virtual display for a "
                    + request.viewType
                    + " with id: "
                    + request.viewId);
          }

          // If our FlutterEngine is already attached to a Flutter UI, provide that Android
          // View to this new platform view.
          if (flutterView != null) {
            vdController.onFlutterViewAttached(flutterView);
          }

          // The embedded view doesn't need to be sized in Virtual Display mode because the
          // virtual display itself is sized.

          vdControllers.put(request.viewId, vdController);
          final View embeddedView = platformView.getView();
          contextToEmbeddedView.put(embeddedView.getContext(), embeddedView);

          return textureEntry.id();
        }

        // Configures the view for Texture Layer Hybrid Composition mode, returning the associated
        // texture ID.
        @TargetApi(23)
        private long configureForTextureLayerComposition(
            @NonNull PlatformView platformView,
            @NonNull PlatformViewsChannel.PlatformViewCreationRequest request) {
          // This mode attaches the view to the Android view hierarchy and record its drawing
          // operations, so they can be forwarded to a GL texture that is composed by the
          // Flutter engine.

          // API level 23 is required to use Surface#lockHardwareCanvas().
          ensureValidAndroidVersion(23);
          Log.i(TAG, "Hosting view in view hierarchy for platform view: " + request.viewId);

          final int physicalWidth = toPhysicalPixels(request.logicalWidth);
          final int physicalHeight = toPhysicalPixels(request.logicalHeight);
          PlatformViewWrapper viewWrapper;
          long textureId;
          if (usesSoftwareRendering) {
            viewWrapper = new PlatformViewWrapper(context);
            textureId = -1;
          } else {
            final TextureRegistry.SurfaceTextureEntry textureEntry =
                textureRegistry.createSurfaceTexture();
            viewWrapper = new PlatformViewWrapper(context, textureEntry);
            textureId = textureEntry.id();
          }
          viewWrapper.setTouchProcessor(androidTouchProcessor);
          viewWrapper.setBufferSize(physicalWidth, physicalHeight);

          final FrameLayout.LayoutParams viewWrapperLayoutParams =
              new FrameLayout.LayoutParams(physicalWidth, physicalHeight);

          // Size and position the view wrapper.
          final int physicalTop = toPhysicalPixels(request.logicalTop);
          final int physicalLeft = toPhysicalPixels(request.logicalLeft);
          viewWrapperLayoutParams.topMargin = physicalTop;
          viewWrapperLayoutParams.leftMargin = physicalLeft;
          viewWrapper.setLayoutParams(viewWrapperLayoutParams);

          // Size the embedded view.
          final View embeddedView = platformView.getView();
          embeddedView.setLayoutParams(new FrameLayout.LayoutParams(physicalWidth, physicalHeight));

          // Accessibility in the embedded view is initially disabled because if a Flutter app
          // disabled accessibility in the first frame, the embedding won't receive an update to
          // disable accessibility since the embedding never received an update to enable it.
          // The AccessibilityBridge keeps track of the accessibility nodes, and handles the deltas
          // when the framework sends a new a11y tree to the embedding.
          // To prevent races, the framework populate the SemanticsNode after the platform view has
          // been created.
          embeddedView.setImportantForAccessibility(
              View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);

          // Add the embedded view to the wrapper.
          viewWrapper.addView(embeddedView);

          // Listen for focus changed in any subview, so the framework is notified when the platform
          // view is focused.
          viewWrapper.setOnDescendantFocusChangeListener(
              (v, hasFocus) -> {
                if (hasFocus) {
                  platformViewsChannel.invokeViewFocused(request.viewId);
                } else if (textInputPlugin != null) {
                  textInputPlugin.clearPlatformViewClient(request.viewId);
                }
              });
          flutterView.addView(viewWrapper);
          viewWrappers.append(request.viewId, viewWrapper);
          return textureId;
        }

        @Override
        public void synchronizeToNativeViewHierarchy(boolean yes) {
          synchronizeToNativeViewHierarchy = yes;
        }
      };

  @VisibleForTesting
  public MotionEvent toMotionEvent(
      float density, PlatformViewsChannel.PlatformViewTouch touch, boolean usingVirtualDiplay) {
    MotionEventTracker.MotionEventId motionEventId =
        MotionEventTracker.MotionEventId.from(touch.motionEventId);
    MotionEvent trackedEvent = motionEventTracker.pop(motionEventId);

    // Pointer coordinates in the tracked events are global to FlutterView
    // framework converts them to be local to a widget, given that
    // motion events operate on local coords, we need to replace these in the tracked
    // event with their local counterparts.
    PointerProperties[] pointerProperties =
        parsePointerPropertiesList(touch.rawPointerPropertiesList)
            .toArray(new PointerProperties[touch.pointerCount]);
    PointerCoords[] pointerCoords =
        parsePointerCoordsList(touch.rawPointerCoords, density)
            .toArray(new PointerCoords[touch.pointerCount]);

    if (!usingVirtualDiplay && trackedEvent != null) {
      return MotionEvent.obtain(
          trackedEvent.getDownTime(),
          trackedEvent.getEventTime(),
          touch.action,
          touch.pointerCount,
          pointerProperties,
          pointerCoords,
          trackedEvent.getMetaState(),
          trackedEvent.getButtonState(),
          trackedEvent.getXPrecision(),
          trackedEvent.getYPrecision(),
          trackedEvent.getDeviceId(),
          trackedEvent.getEdgeFlags(),
          trackedEvent.getSource(),
          trackedEvent.getFlags());
    }

    // TODO (kaushikiska) : warn that we are potentially using an untracked
    // event in the platform views.
    return MotionEvent.obtain(
        touch.downTime.longValue(),
        touch.eventTime.longValue(),
        touch.action,
        touch.pointerCount,
        pointerProperties,
        pointerCoords,
        touch.metaState,
        touch.buttonState,
        touch.xPrecision,
        touch.yPrecision,
        touch.deviceId,
        touch.edgeFlags,
        touch.source,
        touch.flags);
  }

  public PlatformViewsController() {
    registry = new PlatformViewRegistryImpl();
    vdControllers = new HashMap<>();
    accessibilityEventsDelegate = new AccessibilityEventsDelegate();
    contextToEmbeddedView = new HashMap<>();
    overlayLayerViews = new SparseArray<>();
    currentFrameUsedOverlayLayerIds = new HashSet<>();
    currentFrameUsedPlatformViewIds = new HashSet<>();
    viewWrappers = new SparseArray<>();
    platformViews = new SparseArray<>();
    platformViewParent = new SparseArray<>();

    motionEventTracker = MotionEventTracker.getInstance();
  }

  /**
   * Attaches this platform views controller to its input and output channels.
   *
   * @param context The base context that will be passed to embedded views created by this
   *     controller. This should be the context of the Activity hosting the Flutter application.
   * @param textureRegistry The texture registry which provides the output textures into which the
   *     embedded views will be rendered.
   * @param dartExecutor The dart execution context, which is used to set up a system channel.
   */
  public void attach(
      @Nullable Context context,
      @NonNull TextureRegistry textureRegistry,
      @NonNull DartExecutor dartExecutor) {
    if (this.context != null) {
      throw new AssertionError(
          "A PlatformViewsController can only be attached to a single output target.\n"
              + "attach was called while the PlatformViewsController was already attached.");
    }
    this.context = context;
    this.textureRegistry = textureRegistry;
    platformViewsChannel = new PlatformViewsChannel(dartExecutor);
    platformViewsChannel.setPlatformViewsHandler(channelHandler);
  }

  /**
   * Sets whether Flutter uses software rendering.
   *
   * <p>When software rendering is used, no GL context is available on the raster thread. When this
   * is set to true, there's no Flutter composition of Android views and Flutter widgets since GL
   * textures cannot be used.
   *
   * <p>Software rendering is only used for testing in emulators, and it should never be set to true
   * in a production environment.
   *
   * @param useSoftwareRendering Whether software rendering is used.
   */
  public void setSoftwareRendering(boolean useSoftwareRendering) {
    usesSoftwareRendering = useSoftwareRendering;
  }

  /**
   * Detaches this platform views controller.
   *
   * <p>This is typically called when a Flutter applications moves to run in the background, or is
   * destroyed. After calling this the platform views controller will no longer listen to it's
   * previous messenger, and will not maintain references to the texture registry, context, and
   * messenger passed to the previous attach call.
   */
  @UiThread
  public void detach() {
    if (platformViewsChannel != null) {
      platformViewsChannel.setPlatformViewsHandler(null);
    }
    destroyOverlaySurfaces();
    platformViewsChannel = null;
    context = null;
    textureRegistry = null;
  }

  /**
   * Attaches the controller to a {@link FlutterView}.
   *
   * <p>When {@link io.flutter.embedding.android.FlutterFragment} is used, this method is called
   * after the device rotates since the FlutterView is recreated after a rotation.
   */
  public void attachToView(@NonNull FlutterView newFlutterView) {
    flutterView = newFlutterView;
    // Add wrapper for platform views that use GL texture.
    for (int index = 0; index < viewWrappers.size(); index++) {
      final PlatformViewWrapper view = viewWrappers.valueAt(index);
      flutterView.addView(view);
    }
    // Add wrapper for platform views that are composed at the view hierarchy level.
    for (int index = 0; index < platformViewParent.size(); index++) {
      final FlutterMutatorView view = platformViewParent.valueAt(index);
      flutterView.addView(view);
    }
    // Notify platform views that they are now attached to a FlutterView.
    for (int index = 0; index < platformViews.size(); index++) {
      final PlatformView view = platformViews.valueAt(index);
      view.onFlutterViewAttached(flutterView);
    }
  }

  /**
   * Detaches the controller from {@link FlutterView}.
   *
   * <p>When {@link io.flutter.embedding.android.FlutterFragment} is used, this method is called
   * when the device rotates since the FlutterView is detached from the fragment. The next time the
   * fragment needs to be displayed, a new Flutter view is created, so attachToView is called again.
   */
  public void detachFromView() {
    // Remove wrapper for platform views that use GL texture.
    for (int index = 0; index < viewWrappers.size(); index++) {
      final PlatformViewWrapper view = viewWrappers.valueAt(index);
      flutterView.removeView(view);
    }
    // Remove wrapper for platform views that are composed at the view hierarchy level.
    for (int index = 0; index < platformViewParent.size(); index++) {
      final FlutterMutatorView view = platformViewParent.valueAt(index);
      flutterView.removeView(view);
    }

    destroyOverlaySurfaces();
    removeOverlaySurfaces();
    flutterView = null;
    flutterViewConvertedToImageView = false;

    // Notify that the platform view have been detached from FlutterView.
    for (int index = 0; index < platformViews.size(); index++) {
      final PlatformView view = platformViews.valueAt(index);
      view.onFlutterViewDetached();
    }
  }

  @Override
  public void attachAccessibilityBridge(@NonNull AccessibilityBridge accessibilityBridge) {
    accessibilityEventsDelegate.setAccessibilityBridge(accessibilityBridge);
  }

  @Override
  public void detachAccessibilityBridge() {
    accessibilityEventsDelegate.setAccessibilityBridge(null);
  }

  /**
   * Attaches this controller to a text input plugin.
   *
   * <p>While a text input plugin is available, the platform views controller interacts with it to
   * facilitate delegation of text input connections to platform views.
   *
   * <p>A platform views controller should be attached to a text input plugin whenever it is
   * possible for the Flutter framework to receive text input.
   */
  public void attachTextInputPlugin(@NonNull TextInputPlugin textInputPlugin) {
    this.textInputPlugin = textInputPlugin;
  }

  /** Detaches this controller from the currently attached text input plugin. */
  public void detachTextInputPlugin() {
    textInputPlugin = null;
  }

  /**
   * Returns true if Flutter should perform input connection proxying for the view.
   *
   * <p>If the view is a platform view managed by this platform views controller returns true. Else
   * if the view was created in a platform view's VD, delegates the decision to the platform view's
   * {@link View#checkInputConnectionProxy(View)} method. Else returns false.
   */
  public boolean checkInputConnectionProxy(@Nullable View view) {
    // View can be null on some devices
    // See: https://github.com/flutter/flutter/issues/36517
    if (view == null) {
      return false;
    }
    if (!contextToEmbeddedView.containsKey(view.getContext())) {
      return false;
    }
    View platformView = contextToEmbeddedView.get(view.getContext());
    if (platformView == view) {
      return true;
    }
    return platformView.checkInputConnectionProxy(view);
  }

  public PlatformViewRegistry getRegistry() {
    return registry;
  }

  /**
   * Invoked when the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@link
   * PlatformViewsController} attaches to JNI.
   */
  public void onAttachedToJNI() {
    // Currently no action needs to be taken after JNI attachment.
  }

  /**
   * Invoked when the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@link
   * PlatformViewsController} detaches from JNI.
   */
  public void onDetachedFromJNI() {
    diposeAllViews();
  }

  public void onPreEngineRestart() {
    diposeAllViews();
  }

  @Override
  @Nullable
  public View getPlatformViewById(int viewId) {
    if (usesVirtualDisplay(viewId)) {
      final VirtualDisplayController controller = vdControllers.get(viewId);
      return controller.getView();
    }

    final PlatformView platformView = platformViews.get(viewId);
    if (platformView == null) {
      return null;
    }
    return platformView.getView();
  }

  @Override
  public boolean usesVirtualDisplay(int id) {
    return vdControllers.containsKey(id);
  }

  private void lockInputConnection(@NonNull VirtualDisplayController controller) {
    if (textInputPlugin == null) {
      return;
    }
    textInputPlugin.lockPlatformViewInputConnection();
    controller.onInputConnectionLocked();
  }

  private void unlockInputConnection(@NonNull VirtualDisplayController controller) {
    if (textInputPlugin == null) {
      return;
    }
    textInputPlugin.unlockPlatformViewInputConnection();
    controller.onInputConnectionUnlocked();
  }

  private static boolean validateDirection(int direction) {
    return direction == View.LAYOUT_DIRECTION_LTR || direction == View.LAYOUT_DIRECTION_RTL;
  }

  @SuppressWarnings("unchecked")
  private static List<PointerProperties> parsePointerPropertiesList(Object rawPropertiesList) {
    List<Object> rawProperties = (List<Object>) rawPropertiesList;
    List<PointerProperties> pointerProperties = new ArrayList<>();
    for (Object o : rawProperties) {
      pointerProperties.add(parsePointerProperties(o));
    }
    return pointerProperties;
  }

  @SuppressWarnings("unchecked")
  private static PointerProperties parsePointerProperties(Object rawProperties) {
    List<Object> propertiesList = (List<Object>) rawProperties;
    PointerProperties properties = new MotionEvent.PointerProperties();
    properties.id = (int) propertiesList.get(0);
    properties.toolType = (int) propertiesList.get(1);
    return properties;
  }

  @SuppressWarnings("unchecked")
  private static List<PointerCoords> parsePointerCoordsList(Object rawCoordsList, float density) {
    List<Object> rawCoords = (List<Object>) rawCoordsList;
    List<PointerCoords> pointerCoords = new ArrayList<>();
    for (Object o : rawCoords) {
      pointerCoords.add(parsePointerCoords(o, density));
    }
    return pointerCoords;
  }

  @SuppressWarnings("unchecked")
  private static PointerCoords parsePointerCoords(Object rawCoords, float density) {
    List<Object> coordsList = (List<Object>) rawCoords;
    PointerCoords coords = new MotionEvent.PointerCoords();
    coords.orientation = (float) (double) coordsList.get(0);
    coords.pressure = (float) (double) coordsList.get(1);
    coords.size = (float) (double) coordsList.get(2);
    coords.toolMajor = (float) (double) coordsList.get(3) * density;
    coords.toolMinor = (float) (double) coordsList.get(4) * density;
    coords.touchMajor = (float) (double) coordsList.get(5) * density;
    coords.touchMinor = (float) (double) coordsList.get(6) * density;
    coords.x = (float) (double) coordsList.get(7) * density;
    coords.y = (float) (double) coordsList.get(8) * density;
    return coords;
  }

  private float getDisplayDensity() {
    return context.getResources().getDisplayMetrics().density;
  }

  private int toPhysicalPixels(double logicalPixels) {
    return (int) Math.round(logicalPixels * getDisplayDensity());
  }

  private int toLogicalPixels(double physicalPixels, float displayDensity) {
    return (int) Math.round(physicalPixels / displayDensity);
  }

  private int toLogicalPixels(double physicalPixels) {
    return toLogicalPixels(physicalPixels, getDisplayDensity());
  }

  private void diposeAllViews() {
    while (platformViews.size() > 0) {
      final int viewId = platformViews.keyAt(0);
      // Dispose deletes the entry from platformViews and clears associated resources.
      channelHandler.dispose(viewId);
    }
  }

  private void initializeRootImageViewIfNeeded() {
    if (synchronizeToNativeViewHierarchy && !flutterViewConvertedToImageView) {
      flutterView.convertToImageView();
      flutterViewConvertedToImageView = true;
    }
  }

  /**
   * Initializes a platform view and adds it to the view hierarchy.
   *
   * @param viewId The view ID. This member is not intended for public use, and is only visible for
   *     testing.
   */
  @VisibleForTesting
  @TargetApi(Build.VERSION_CODES.KITKAT)
  void initializePlatformViewIfNeeded(int viewId) {
    final PlatformView platformView = platformViews.get(viewId);
    if (platformView == null) {
      throw new IllegalStateException(
          "Platform view hasn't been initialized from the platform view channel.");
    }
    if (platformViewParent.get(viewId) != null) {
      return;
    }
    final View embeddedView = platformView.getView();
    if (embeddedView == null) {
      throw new IllegalStateException(
          "PlatformView#getView() returned null, but an Android view reference was expected.");
    }
    if (embeddedView.getParent() != null) {
      throw new IllegalStateException(
          "The Android view returned from PlatformView#getView() was already added to a parent view.");
    }
    final FlutterMutatorView parentView =
        new FlutterMutatorView(
            context, context.getResources().getDisplayMetrics().density, androidTouchProcessor);

    parentView.setOnDescendantFocusChangeListener(
        (view, hasFocus) -> {
          if (hasFocus) {
            platformViewsChannel.invokeViewFocused(viewId);
          } else if (textInputPlugin != null) {
            textInputPlugin.clearPlatformViewClient(viewId);
          }
        });

    platformViewParent.put(viewId, parentView);

    // Accessibility in the embedded view is initially disabled because if a Flutter app disabled
    // accessibility in the first frame, the embedding won't receive an update to disable
    // accessibility since the embedding never received an update to enable it.
    // The AccessibilityBridge keeps track of the accessibility nodes, and handles the deltas when
    // the framework sends a new a11y tree to the embedding.
    // To prevent races, the framework populate the SemanticsNode after the platform view has been
    // created.
    embeddedView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);

    parentView.addView(embeddedView);
    flutterView.addView(parentView);
  }

  public void attachToFlutterRenderer(@NonNull FlutterRenderer flutterRenderer) {
    androidTouchProcessor = new AndroidTouchProcessor(flutterRenderer, /*trackMotionEvents=*/ true);
  }

  /**
   * Called when a platform view id displayed in the current frame.
   *
   * @param viewId The ID of the platform view.
   * @param x The left position relative to {@code FlutterView}.
   * @param y The top position relative to {@code FlutterView}.
   * @param width The width of the platform view.
   * @param height The height of the platform view.
   * @param viewWidth The original width of the platform view before applying the mutator stack.
   * @param viewHeight The original height of the platform view before applying the mutator stack.
   * @param mutatorsStack The mutator stack. This member is not intended for public use, and is only
   *     visible for testing.
   */
  public void onDisplayPlatformView(
      int viewId,
      int x,
      int y,
      int width,
      int height,
      int viewWidth,
      int viewHeight,
      @NonNull FlutterMutatorsStack mutatorsStack) {
    initializeRootImageViewIfNeeded();
    initializePlatformViewIfNeeded(viewId);

    final FlutterMutatorView parentView = platformViewParent.get(viewId);
    parentView.readyToDisplay(mutatorsStack, x, y, width, height);
    parentView.setVisibility(View.VISIBLE);
    parentView.bringToFront();

    final FrameLayout.LayoutParams layoutParams =
        new FrameLayout.LayoutParams(viewWidth, viewHeight);
    final View view = platformViews.get(viewId).getView();
    if (view != null) {
      view.setLayoutParams(layoutParams);
      view.bringToFront();
    }
    currentFrameUsedPlatformViewIds.add(viewId);
  }

  /**
   * Called when an overlay surface is displayed in the current frame.
   *
   * @param id The ID of the surface.
   * @param x The left position relative to {@code FlutterView}.
   * @param y The top position relative to {@code FlutterView}.
   * @param width The width of the surface.
   * @param height The height of the surface. This member is not intended for public use, and is
   *     only visible for testing.
   */
  public void onDisplayOverlaySurface(int id, int x, int y, int width, int height) {
    if (overlayLayerViews.get(id) == null) {
      throw new IllegalStateException("The overlay surface (id:" + id + ") doesn't exist");
    }
    initializeRootImageViewIfNeeded();

    final PlatformOverlayView overlayView = overlayLayerViews.get(id);
    if (overlayView.getParent() == null) {
      flutterView.addView(overlayView);
    }

    FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams((int) width, (int) height);
    layoutParams.leftMargin = (int) x;
    layoutParams.topMargin = (int) y;
    overlayView.setLayoutParams(layoutParams);
    overlayView.setVisibility(View.VISIBLE);
    overlayView.bringToFront();
    currentFrameUsedOverlayLayerIds.add(id);
  }

  public void onBeginFrame() {
    currentFrameUsedOverlayLayerIds.clear();
    currentFrameUsedPlatformViewIds.clear();
  }

  /**
   * Called by {@code FlutterJNI} when the Flutter frame was submitted.
   *
   * <p>This member is not intended for public use, and is only visible for testing.
   */
  public void onEndFrame() {
    // If there are no platform views in the current frame,
    // then revert the image view surface and use the previous surface.
    //
    // Otherwise, acquire the latest image.
    if (flutterViewConvertedToImageView && currentFrameUsedPlatformViewIds.isEmpty()) {
      flutterViewConvertedToImageView = false;
      flutterView.revertImageView(
          () -> {
            // Destroy overlay surfaces once the surface reversion is completed.
            finishFrame(false);
          });
      return;
    }
    // Whether the current frame was rendered using ImageReaders.
    //
    // Since the image readers may not have images available at this point,
    // this becomes true if all the required surfaces have images available.
    //
    // This is used to decide if the platform views can be rendered in the current frame.
    // If one of the surfaces doesn't have an image, the frame may be incomplete and must be
    // dropped.
    // For example, a toolbar widget painted by Flutter may not be rendered.
    final boolean isFrameRenderedUsingImageReaders =
        flutterViewConvertedToImageView && flutterView.acquireLatestImageViewFrame();
    finishFrame(isFrameRenderedUsingImageReaders);
  }

  private void finishFrame(boolean isFrameRenderedUsingImageReaders) {
    for (int i = 0; i < overlayLayerViews.size(); i++) {
      final int overlayId = overlayLayerViews.keyAt(i);
      final PlatformOverlayView overlayView = overlayLayerViews.valueAt(i);

      if (currentFrameUsedOverlayLayerIds.contains(overlayId)) {
        flutterView.attachOverlaySurfaceToRender(overlayView);
        final boolean didAcquireOverlaySurfaceImage = overlayView.acquireLatestImage();
        isFrameRenderedUsingImageReaders &= didAcquireOverlaySurfaceImage;
      } else {
        // If the background surface isn't rendered by the image view, then the
        // overlay surfaces can be detached from the rendered.
        // This releases resources used by the ImageReader.
        if (!flutterViewConvertedToImageView) {
          overlayView.detachFromRenderer();
        }
        // Hide overlay surfaces that aren't rendered in the current frame.
        overlayView.setVisibility(View.GONE);
        flutterView.removeView(overlayView);
      }
    }

    for (int i = 0; i < platformViewParent.size(); i++) {
      final int viewId = platformViewParent.keyAt(i);
      final View parentView = platformViewParent.get(viewId);

      // This should only show platform views that are rendered in this frame and either:
      //  1. Surface has images available in this frame or,
      //  2. Surface does not have images available in this frame because the render surface should
      // not be an ImageView.
      //
      // The platform view is appended to a mutator view.
      //
      // Otherwise, hide the platform view, but don't remove it from the view hierarchy yet as
      // they are removed when the framework disposes the platform view widget.
      if (currentFrameUsedPlatformViewIds.contains(viewId)
          && (isFrameRenderedUsingImageReaders || !synchronizeToNativeViewHierarchy)) {
        parentView.setVisibility(View.VISIBLE);
      } else {
        parentView.setVisibility(View.GONE);
      }
    }
  }

  /**
   * Creates and tracks the overlay surface.
   *
   * @param imageView The surface that displays the overlay.
   * @return Wrapper object that provides the layer id and the surface. This member is not intended
   *     for public use, and is only visible for testing.
   */
  @VisibleForTesting
  @TargetApi(19)
  @NonNull
  public FlutterOverlaySurface createOverlaySurface(@NonNull PlatformOverlayView imageView) {
    final int id = nextOverlayLayerId++;
    overlayLayerViews.put(id, imageView);
    return new FlutterOverlaySurface(id, imageView.getSurface());
  }

  /**
   * Creates an overlay surface while the Flutter view is rendered by {@code PlatformOverlayView}.
   *
   * <p>This method is invoked by {@code FlutterJNI} only.
   *
   * <p>This member is not intended for public use, and is only visible for testing.
   */
  @TargetApi(19)
  @NonNull
  public FlutterOverlaySurface createOverlaySurface() {
    // Overlay surfaces have the same size as the background surface.
    //
    // This allows to reuse these surfaces in consecutive frames even
    // if the drawings they contain have a different tight bound.
    //
    // The final view size is determined when its frame is set.
    return createOverlaySurface(
        new PlatformOverlayView(
            flutterView.getContext(),
            flutterView.getWidth(),
            flutterView.getHeight(),
            accessibilityEventsDelegate));
  }

  /**
   * Destroys the overlay surfaces and removes them from the view hierarchy.
   *
   * <p>This method is used only internally by {@code FlutterJNI}.
   */
  public void destroyOverlaySurfaces() {
    for (int viewId = 0; viewId < overlayLayerViews.size(); viewId++) {
      final PlatformOverlayView overlayView = overlayLayerViews.valueAt(viewId);
      overlayView.detachFromRenderer();
      overlayView.closeImageReader();
      // Don't remove overlayView from the view hierarchy since this method can
      // be called while the Android framework is iterating over the array of views.
      // See ViewGroup#dispatchDetachedFromWindow(), and
      // https://github.com/flutter/flutter/issues/97679.
    }
  }

  private void removeOverlaySurfaces() {
    if (flutterView == null) {
      Log.e(TAG, "removeOverlaySurfaces called while flutter view is null");
      return;
    }
    for (int viewId = 0; viewId < overlayLayerViews.size(); viewId++) {
      flutterView.removeView(overlayLayerViews.valueAt(viewId));
    }
    overlayLayerViews.clear();
  }

  @VisibleForTesting
  public SparseArray<PlatformOverlayView> getOverlayLayerViews() {
    return overlayLayerViews;
  }
}
