// 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.view;

import static io.flutter.Build.API_LEVELS;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.SurfaceTexture;
import android.os.Build;
import android.os.Handler;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.DisplayCutout;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.PointerIcon;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewStructure;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.autofill.AutofillValue;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.annotation.UiThread;
import io.flutter.Log;
import io.flutter.app.FlutterPluginRegistry;
import io.flutter.embedding.android.AndroidTouchProcessor;
import io.flutter.embedding.android.KeyboardManager;
import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.embedding.engine.renderer.FlutterRenderer;
import io.flutter.embedding.engine.renderer.SurfaceTextureWrapper;
import io.flutter.embedding.engine.systemchannels.AccessibilityChannel;
import io.flutter.embedding.engine.systemchannels.LifecycleChannel;
import io.flutter.embedding.engine.systemchannels.LocalizationChannel;
import io.flutter.embedding.engine.systemchannels.MouseCursorChannel;
import io.flutter.embedding.engine.systemchannels.NavigationChannel;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
import io.flutter.embedding.engine.systemchannels.SettingsChannel;
import io.flutter.embedding.engine.systemchannels.SystemChannel;
import io.flutter.embedding.engine.systemchannels.TextInputChannel;
import io.flutter.plugin.common.ActivityLifecycleListener;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.editing.TextInputPlugin;
import io.flutter.plugin.localization.LocalizationPlugin;
import io.flutter.plugin.mouse.MouseCursorPlugin;
import io.flutter.plugin.platform.PlatformPlugin;
import io.flutter.plugin.platform.PlatformViewsController;
import io.flutter.util.ViewUtils;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Deprecated Android view containing a Flutter app.
 *
 * @deprecated {@link io.flutter.embedding.android.FlutterView} is the new API that now replaces
 *     this class. See https://flutter.dev/go/android-project-migration for more migration details.
 */
@Deprecated
public class FlutterView extends SurfaceView
    implements BinaryMessenger,
        TextureRegistry,
        MouseCursorPlugin.MouseCursorViewDelegate,
        KeyboardManager.ViewDelegate {
  /**
   * Interface for those objects that maintain and expose a reference to a {@code FlutterView} (such
   * as a full-screen Flutter activity).
   *
   * <p>This indirection is provided to support applications that use an activity other than {@link
   * io.flutter.app.FlutterActivity} (e.g. Android v4 support library's {@code FragmentActivity}).
   * It allows Flutter plugins to deal in this interface and not require that the activity be a
   * subclass of {@code FlutterActivity}.
   */
  public interface Provider {
    /**
     * Returns a reference to the Flutter view maintained by this object. This may be {@code null}.
     *
     * @return a reference to the Flutter view maintained by this object.
     */
    FlutterView getFlutterView();
  }

  private static final String TAG = "FlutterView";

  static final class ViewportMetrics {
    float devicePixelRatio = 1.0f;
    int physicalWidth = 0;
    int physicalHeight = 0;
    int physicalViewPaddingTop = 0;
    int physicalViewPaddingRight = 0;
    int physicalViewPaddingBottom = 0;
    int physicalViewPaddingLeft = 0;
    int physicalViewInsetTop = 0;
    int physicalViewInsetRight = 0;
    int physicalViewInsetBottom = 0;
    int physicalViewInsetLeft = 0;
    int systemGestureInsetTop = 0;
    int systemGestureInsetRight = 0;
    int systemGestureInsetBottom = 0;
    int systemGestureInsetLeft = 0;
    int physicalTouchSlop = -1;
  }

  private final DartExecutor dartExecutor;
  private final FlutterRenderer flutterRenderer;
  private final NavigationChannel navigationChannel;
  private final LifecycleChannel lifecycleChannel;
  private final LocalizationChannel localizationChannel;
  private final PlatformChannel platformChannel;
  private final SettingsChannel settingsChannel;
  private final SystemChannel systemChannel;
  private final InputMethodManager mImm;
  private final TextInputPlugin mTextInputPlugin;
  private final LocalizationPlugin mLocalizationPlugin;
  private final MouseCursorPlugin mMouseCursorPlugin;
  private final KeyboardManager mKeyboardManager;
  private final AndroidTouchProcessor androidTouchProcessor;
  private AccessibilityBridge mAccessibilityNodeProvider;
  private final SurfaceHolder.Callback mSurfaceCallback;
  private final ViewportMetrics mMetrics;
  private final List<ActivityLifecycleListener> mActivityLifecycleListeners;
  private final List<FirstFrameListener> mFirstFrameListeners;
  private final AtomicLong nextTextureId = new AtomicLong(0L);
  private FlutterNativeView mNativeView;
  private boolean mIsSoftwareRenderingEnabled = false; // using the software renderer or not
  private boolean didRenderFirstFrame = false;

  private final AccessibilityBridge.OnAccessibilityChangeListener onAccessibilityChangeListener =
      new AccessibilityBridge.OnAccessibilityChangeListener() {
        @Override
        public void onAccessibilityChanged(
            boolean isAccessibilityEnabled, boolean isTouchExplorationEnabled) {
          resetWillNotDraw(isAccessibilityEnabled, isTouchExplorationEnabled);
        }
      };

  public FlutterView(Context context) {
    this(context, null);
  }

  public FlutterView(Context context, AttributeSet attrs) {
    this(context, attrs, null);
  }

  public FlutterView(Context context, AttributeSet attrs, FlutterNativeView nativeView) {
    super(context, attrs);

    Activity activity = ViewUtils.getActivity(getContext());
    if (activity == null) {
      throw new IllegalArgumentException("Bad context");
    }

    if (nativeView == null) {
      mNativeView = new FlutterNativeView(activity.getApplicationContext());
    } else {
      mNativeView = nativeView;
    }

    dartExecutor = mNativeView.getDartExecutor();
    flutterRenderer = new FlutterRenderer(mNativeView.getFlutterJNI());
    mIsSoftwareRenderingEnabled = mNativeView.getFlutterJNI().getIsSoftwareRenderingEnabled();
    mMetrics = new ViewportMetrics();
    mMetrics.devicePixelRatio = context.getResources().getDisplayMetrics().density;
    mMetrics.physicalTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    setFocusable(true);
    setFocusableInTouchMode(true);

    mNativeView.attachViewAndActivity(this, activity);

    mSurfaceCallback =
        new SurfaceHolder.Callback() {
          @Override
          public void surfaceCreated(SurfaceHolder holder) {
            assertAttached();
            mNativeView.getFlutterJNI().onSurfaceCreated(holder.getSurface());
          }

          @Override
          public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            assertAttached();
            mNativeView.getFlutterJNI().onSurfaceChanged(width, height);
          }

          @Override
          public void surfaceDestroyed(SurfaceHolder holder) {
            assertAttached();
            mNativeView.getFlutterJNI().onSurfaceDestroyed();
          }
        };
    getHolder().addCallback(mSurfaceCallback);

    mActivityLifecycleListeners = new ArrayList<>();
    mFirstFrameListeners = new ArrayList<>();

    // Create all platform channels
    navigationChannel = new NavigationChannel(dartExecutor);
    lifecycleChannel = new LifecycleChannel(dartExecutor);
    localizationChannel = new LocalizationChannel(dartExecutor);
    platformChannel = new PlatformChannel(dartExecutor);
    systemChannel = new SystemChannel(dartExecutor);
    settingsChannel = new SettingsChannel(dartExecutor);

    // Create and set up plugins
    PlatformPlugin platformPlugin = new PlatformPlugin(activity, platformChannel);
    addActivityLifecycleListener(
        new ActivityLifecycleListener() {
          @Override
          public void onPostResume() {
            platformPlugin.updateSystemUiOverlays();
          }
        });
    mImm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
    PlatformViewsController platformViewsController =
        mNativeView.getPluginRegistry().getPlatformViewsController();
    mTextInputPlugin =
        new TextInputPlugin(this, new TextInputChannel(dartExecutor), platformViewsController);
    mKeyboardManager = new KeyboardManager(this);

    if (Build.VERSION.SDK_INT >= API_LEVELS.API_24) {
      mMouseCursorPlugin = new MouseCursorPlugin(this, new MouseCursorChannel(dartExecutor));
    } else {
      mMouseCursorPlugin = null;
    }
    mLocalizationPlugin = new LocalizationPlugin(context, localizationChannel);
    androidTouchProcessor =
        new AndroidTouchProcessor(flutterRenderer, /*trackMotionEvents=*/ false);
    platformViewsController.attachToFlutterRenderer(flutterRenderer);
    mNativeView
        .getPluginRegistry()
        .getPlatformViewsController()
        .attachTextInputPlugin(mTextInputPlugin);
    mNativeView.getFlutterJNI().setLocalizationPlugin(mLocalizationPlugin);

    // Send initial platform information to Dart
    mLocalizationPlugin.sendLocalesToFlutter(getResources().getConfiguration());
    sendUserPlatformSettingsToDart();
  }

  @NonNull
  public DartExecutor getDartExecutor() {
    return dartExecutor;
  }

  @Override
  public boolean dispatchKeyEvent(KeyEvent event) {
    Log.e(TAG, "dispatchKeyEvent: " + event.toString());
    if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
      // Tell Android to start tracking this event.
      getKeyDispatcherState().startTracking(event, this);
    } else if (event.getAction() == KeyEvent.ACTION_UP) {
      // Stop tracking the event.
      getKeyDispatcherState().handleUpEvent(event);
    }
    // If the key processor doesn't handle it, then send it on to the
    // superclass. The key processor will typically handle all events except
    // those where it has re-dispatched the event after receiving a reply from
    // the framework that the framework did not handle it.
    return (isAttached() && mKeyboardManager.handleEvent(event)) || super.dispatchKeyEvent(event);
  }

  public FlutterNativeView getFlutterNativeView() {
    return mNativeView;
  }

  public FlutterPluginRegistry getPluginRegistry() {
    return mNativeView.getPluginRegistry();
  }

  public String getLookupKeyForAsset(String asset) {
    return FlutterMain.getLookupKeyForAsset(asset);
  }

  public String getLookupKeyForAsset(String asset, String packageName) {
    return FlutterMain.getLookupKeyForAsset(asset, packageName);
  }

  public void addActivityLifecycleListener(ActivityLifecycleListener listener) {
    mActivityLifecycleListeners.add(listener);
  }

  public void onStart() {
    lifecycleChannel.appIsInactive();
  }

  public void onPause() {
    lifecycleChannel.appIsInactive();
  }

  public void onPostResume() {
    for (ActivityLifecycleListener listener : mActivityLifecycleListeners) {
      listener.onPostResume();
    }
    lifecycleChannel.appIsResumed();
  }

  public void onStop() {
    lifecycleChannel.appIsPaused();
  }

  public void onMemoryPressure() {
    mNativeView.getFlutterJNI().notifyLowMemoryWarning();
    systemChannel.sendMemoryPressureWarning();
  }

  /**
   * Returns true if the Flutter experience associated with this {@code FlutterView} has rendered
   * its first frame, or false otherwise.
   */
  public boolean hasRenderedFirstFrame() {
    return didRenderFirstFrame;
  }

  /**
   * Provide a listener that will be called once when the FlutterView renders its first frame to the
   * underlaying SurfaceView.
   */
  public void addFirstFrameListener(FirstFrameListener listener) {
    mFirstFrameListeners.add(listener);
  }

  /** Remove an existing first frame listener. */
  public void removeFirstFrameListener(FirstFrameListener listener) {
    mFirstFrameListeners.remove(listener);
  }

  @Override
  public void enableBufferingIncomingMessages() {}

  @Override
  public void disableBufferingIncomingMessages() {}

  /**
   * Reverts this back to the {@link SurfaceView} defaults, at the back of its window and opaque.
   */
  public void disableTransparentBackground() {
    setZOrderOnTop(false);
    getHolder().setFormat(PixelFormat.OPAQUE);
  }

  public void setInitialRoute(String route) {
    navigationChannel.setInitialRoute(route);
  }

  public void pushRoute(String route) {
    navigationChannel.pushRoute(route);
  }

  public void popRoute() {
    navigationChannel.popRoute();
  }

  private void sendUserPlatformSettingsToDart() {
    // Lookup the current brightness of the Android OS.
    boolean isNightModeOn =
        (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK)
            == Configuration.UI_MODE_NIGHT_YES;
    SettingsChannel.PlatformBrightness brightness =
        isNightModeOn
            ? SettingsChannel.PlatformBrightness.dark
            : SettingsChannel.PlatformBrightness.light;

    settingsChannel
        .startMessage()
        .setTextScaleFactor(getResources().getConfiguration().fontScale)
        .setUse24HourFormat(DateFormat.is24HourFormat(getContext()))
        .setPlatformBrightness(brightness)
        .send();
  }

  @Override
  protected void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    mLocalizationPlugin.sendLocalesToFlutter(newConfig);
    sendUserPlatformSettingsToDart();
  }

  float getDevicePixelRatio() {
    return mMetrics.devicePixelRatio;
  }

  public FlutterNativeView detach() {
    if (!isAttached()) return null;
    getHolder().removeCallback(mSurfaceCallback);
    mNativeView.detachFromFlutterView();

    FlutterNativeView view = mNativeView;
    mNativeView = null;
    return view;
  }

  public void destroy() {
    if (!isAttached()) return;

    getHolder().removeCallback(mSurfaceCallback);
    releaseAccessibilityNodeProvider();

    mNativeView.destroy();
    mNativeView = null;
  }

  @Override
  public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    return mTextInputPlugin.createInputConnection(this, mKeyboardManager, outAttrs);
  }

  @Override
  public boolean checkInputConnectionProxy(View view) {
    return mNativeView
        .getPluginRegistry()
        .getPlatformViewsController()
        .checkInputConnectionProxy(view);
  }

  @Override
  public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {
    super.onProvideAutofillVirtualStructure(structure, flags);
    mTextInputPlugin.onProvideAutofillVirtualStructure(structure, flags);
  }

  @Override
  public void autofill(SparseArray<AutofillValue> values) {
    mTextInputPlugin.autofill(values);
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    if (!isAttached()) {
      return super.onTouchEvent(event);
    }

    requestUnbufferedDispatch(event);

    return androidTouchProcessor.onTouchEvent(event);
  }

  @Override
  public boolean onHoverEvent(MotionEvent event) {
    if (!isAttached()) {
      return super.onHoverEvent(event);
    }

    boolean handled = mAccessibilityNodeProvider.onAccessibilityHoverEvent(event);
    if (!handled) {
      // TODO(ianh): Expose hover events to the platform,
      // implementing ADD, REMOVE, etc.
    }
    return handled;
  }

  /**
   * Invoked by Android when a generic motion event occurs, e.g., joystick movement, mouse hover,
   * track pad touches, scroll wheel movements, etc.
   *
   * <p>Flutter handles all of its own gesture detection and processing, therefore this method
   * forwards all {@link MotionEvent} data from Android to Flutter.
   */
  @Override
  public boolean onGenericMotionEvent(MotionEvent event) {
    boolean handled =
        isAttached() && androidTouchProcessor.onGenericMotionEvent(event, getContext());
    return handled ? true : super.onGenericMotionEvent(event);
  }

  @Override
  protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
    mMetrics.physicalWidth = width;
    mMetrics.physicalHeight = height;
    updateViewportMetrics();
    super.onSizeChanged(width, height, oldWidth, oldHeight);
  }

  // TODO(garyq): Add support for notch cutout API
  // Decide if we want to zero the padding of the sides. When in Landscape orientation,
  // android may decide to place the software navigation bars on the side. When the nav
  // bar is hidden, the reported insets should be removed to prevent extra useless space
  // on the sides.
  private enum ZeroSides {
    NONE,
    LEFT,
    RIGHT,
    BOTH
  }

  private ZeroSides calculateShouldZeroSides() {
    // We get both orientation and rotation because rotation is all 4
    // rotations relative to default rotation while orientation is portrait
    // or landscape. By combining both, we can obtain a more precise measure
    // of the rotation.
    Context context = getContext();
    int orientation = context.getResources().getConfiguration().orientation;
    int rotation =
        ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE))
            .getDefaultDisplay()
            .getRotation();

    if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
      if (rotation == Surface.ROTATION_90) {
        return ZeroSides.RIGHT;
      } else if (rotation == Surface.ROTATION_270) {
        // In android API >= 23, the nav bar always appears on the "bottom" (USB) side.
        return Build.VERSION.SDK_INT >= API_LEVELS.API_23 ? ZeroSides.LEFT : ZeroSides.RIGHT;
      }
      // Ambiguous orientation due to landscape left/right default. Zero both sides.
      else if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
        return ZeroSides.BOTH;
      }
    }
    // Square orientation deprecated in API 16, we will not check for it and return false
    // to be safe and not remove any unique padding for the devices that do use it.
    return ZeroSides.NONE;
  }

  // TODO(garyq): Use new Android R getInsets API
  // TODO(garyq): The keyboard detection may interact strangely with
  //   https://github.com/flutter/flutter/issues/22061

  // Uses inset heights and screen heights as a heuristic to determine if the insets should
  // be padded. When the on-screen keyboard is detected, we want to include the full inset
  // but when the inset is just the hidden nav bar, we want to provide a zero inset so the space
  // can be used.

  private int guessBottomKeyboardInset(WindowInsets insets) {
    int screenHeight = getRootView().getHeight();
    // Magic number due to this being a heuristic. This should be replaced, but we have not
    // found a clean way to do it yet (Sept. 2018)
    final double keyboardHeightRatioHeuristic = 0.18;
    if (insets.getSystemWindowInsetBottom() < screenHeight * keyboardHeightRatioHeuristic) {
      // Is not a keyboard, so return zero as inset.
      return 0;
    } else {
      // Is a keyboard, so return the full inset.
      return insets.getSystemWindowInsetBottom();
    }
  }

  // This callback is not present in API < 20, which means lower API devices will see
  // the wider than expected padding when the status and navigation bars are hidden.
  // The annotations to suppress "InlinedApi" and "NewApi" lints prevent lint warnings
  // caused by usage of Android Q APIs. These calls are safe because they are
  // guarded.
  @Override
  @SuppressLint({"InlinedApi", "NewApi"})
  public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
    // getSystemGestureInsets() was introduced in API 29 and immediately deprecated in 30.
    if (Build.VERSION.SDK_INT == API_LEVELS.API_29) {
      Insets systemGestureInsets = insets.getSystemGestureInsets();
      mMetrics.systemGestureInsetTop = systemGestureInsets.top;
      mMetrics.systemGestureInsetRight = systemGestureInsets.right;
      mMetrics.systemGestureInsetBottom = systemGestureInsets.bottom;
      mMetrics.systemGestureInsetLeft = systemGestureInsets.left;
    }

    boolean statusBarVisible = (SYSTEM_UI_FLAG_FULLSCREEN & getWindowSystemUiVisibility()) == 0;
    boolean navigationBarVisible =
        (SYSTEM_UI_FLAG_HIDE_NAVIGATION & getWindowSystemUiVisibility()) == 0;

    if (Build.VERSION.SDK_INT >= API_LEVELS.API_30) {
      int mask = 0;
      if (navigationBarVisible) {
        mask = mask | android.view.WindowInsets.Type.navigationBars();
      }
      if (statusBarVisible) {
        mask = mask | android.view.WindowInsets.Type.statusBars();
      }
      Insets uiInsets = insets.getInsets(mask);
      mMetrics.physicalViewPaddingTop = uiInsets.top;
      mMetrics.physicalViewPaddingRight = uiInsets.right;
      mMetrics.physicalViewPaddingBottom = uiInsets.bottom;
      mMetrics.physicalViewPaddingLeft = uiInsets.left;

      Insets imeInsets = insets.getInsets(android.view.WindowInsets.Type.ime());
      mMetrics.physicalViewInsetTop = imeInsets.top;
      mMetrics.physicalViewInsetRight = imeInsets.right;
      mMetrics.physicalViewInsetBottom = imeInsets.bottom; // Typically, only bottom is non-zero
      mMetrics.physicalViewInsetLeft = imeInsets.left;

      Insets systemGestureInsets =
          insets.getInsets(android.view.WindowInsets.Type.systemGestures());
      mMetrics.systemGestureInsetTop = systemGestureInsets.top;
      mMetrics.systemGestureInsetRight = systemGestureInsets.right;
      mMetrics.systemGestureInsetBottom = systemGestureInsets.bottom;
      mMetrics.systemGestureInsetLeft = systemGestureInsets.left;

      // TODO(garyq): Expose the full rects of the display cutout.

      // Take the max of the display cutout insets and existing padding to merge them
      DisplayCutout cutout = insets.getDisplayCutout();
      if (cutout != null) {
        Insets waterfallInsets = cutout.getWaterfallInsets();
        mMetrics.physicalViewPaddingTop =
            Math.max(
                Math.max(mMetrics.physicalViewPaddingTop, waterfallInsets.top),
                cutout.getSafeInsetTop());
        mMetrics.physicalViewPaddingRight =
            Math.max(
                Math.max(mMetrics.physicalViewPaddingRight, waterfallInsets.right),
                cutout.getSafeInsetRight());
        mMetrics.physicalViewPaddingBottom =
            Math.max(
                Math.max(mMetrics.physicalViewPaddingBottom, waterfallInsets.bottom),
                cutout.getSafeInsetBottom());
        mMetrics.physicalViewPaddingLeft =
            Math.max(
                Math.max(mMetrics.physicalViewPaddingLeft, waterfallInsets.left),
                cutout.getSafeInsetLeft());
      }
    } else {
      // We zero the left and/or right sides to prevent the padding the
      // navigation bar would have caused.
      ZeroSides zeroSides = ZeroSides.NONE;
      if (!navigationBarVisible) {
        zeroSides = calculateShouldZeroSides();
      }

      // Status bar (top), navigation bar (bottom) and left/right system insets should
      // partially obscure the content (padding).
      mMetrics.physicalViewPaddingTop = statusBarVisible ? insets.getSystemWindowInsetTop() : 0;
      mMetrics.physicalViewPaddingRight =
          zeroSides == ZeroSides.RIGHT || zeroSides == ZeroSides.BOTH
              ? 0
              : insets.getSystemWindowInsetRight();
      mMetrics.physicalViewPaddingBottom =
          navigationBarVisible && guessBottomKeyboardInset(insets) == 0
              ? insets.getSystemWindowInsetBottom()
              : 0;
      mMetrics.physicalViewPaddingLeft =
          zeroSides == ZeroSides.LEFT || zeroSides == ZeroSides.BOTH
              ? 0
              : insets.getSystemWindowInsetLeft();

      // Bottom system inset (keyboard) should adjust scrollable bottom edge (inset).
      mMetrics.physicalViewInsetTop = 0;
      mMetrics.physicalViewInsetRight = 0;
      mMetrics.physicalViewInsetBottom = guessBottomKeyboardInset(insets);
      mMetrics.physicalViewInsetLeft = 0;
    }

    updateViewportMetrics();
    return super.onApplyWindowInsets(insets);
  }

  private boolean isAttached() {
    return mNativeView != null && mNativeView.isAttached();
  }

  void assertAttached() {
    if (!isAttached()) throw new AssertionError("Platform view is not attached");
  }

  private void preRun() {
    resetAccessibilityTree();
  }

  void resetAccessibilityTree() {
    if (mAccessibilityNodeProvider != null) {
      mAccessibilityNodeProvider.reset();
    }
  }

  private void postRun() {}

  public void runFromBundle(FlutterRunArguments args) {
    assertAttached();
    preRun();
    mNativeView.runFromBundle(args);
    postRun();
  }

  /**
   * Return the most recent frame as a bitmap.
   *
   * @return A bitmap.
   */
  public Bitmap getBitmap() {
    assertAttached();
    return mNativeView.getFlutterJNI().getBitmap();
  }

  private void updateViewportMetrics() {
    if (!isAttached()) return;
    mNativeView
        .getFlutterJNI()
        .setViewportMetrics(
            mMetrics.devicePixelRatio,
            mMetrics.physicalWidth,
            mMetrics.physicalHeight,
            mMetrics.physicalViewPaddingTop,
            mMetrics.physicalViewPaddingRight,
            mMetrics.physicalViewPaddingBottom,
            mMetrics.physicalViewPaddingLeft,
            mMetrics.physicalViewInsetTop,
            mMetrics.physicalViewInsetRight,
            mMetrics.physicalViewInsetBottom,
            mMetrics.physicalViewInsetLeft,
            mMetrics.systemGestureInsetTop,
            mMetrics.systemGestureInsetRight,
            mMetrics.systemGestureInsetBottom,
            mMetrics.systemGestureInsetLeft,
            mMetrics.physicalTouchSlop,
            new int[0],
            new int[0],
            new int[0]);
  }

  // Called by FlutterNativeView to notify first Flutter frame rendered.
  public void onFirstFrame() {
    didRenderFirstFrame = true;

    // Allow listeners to remove themselves when they are called.
    List<FirstFrameListener> listeners = new ArrayList<>(mFirstFrameListeners);
    for (FirstFrameListener listener : listeners) {
      listener.onFirstFrame();
    }
  }

  @Override
  protected void onAttachedToWindow() {
    super.onAttachedToWindow();

    PlatformViewsController platformViewsController =
        getPluginRegistry().getPlatformViewsController();
    mAccessibilityNodeProvider =
        new AccessibilityBridge(
            this,
            new AccessibilityChannel(dartExecutor, getFlutterNativeView().getFlutterJNI()),
            (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE),
            getContext().getContentResolver(),
            platformViewsController);
    mAccessibilityNodeProvider.setOnAccessibilityChangeListener(onAccessibilityChangeListener);

    resetWillNotDraw(
        mAccessibilityNodeProvider.isAccessibilityEnabled(),
        mAccessibilityNodeProvider.isTouchExplorationEnabled());
  }

  @Override
  protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    releaseAccessibilityNodeProvider();
  }

  // TODO(mattcarroll): Confer with Ian as to why we need this method. Delete if possible, otherwise
  // add comments.
  private void resetWillNotDraw(boolean isAccessibilityEnabled, boolean isTouchExplorationEnabled) {
    if (!mIsSoftwareRenderingEnabled) {
      setWillNotDraw(!(isAccessibilityEnabled || isTouchExplorationEnabled));
    } else {
      setWillNotDraw(false);
    }
  }

  @Override
  public AccessibilityNodeProvider getAccessibilityNodeProvider() {
    if (mAccessibilityNodeProvider != null && mAccessibilityNodeProvider.isAccessibilityEnabled()) {
      return mAccessibilityNodeProvider;
    } else {
      // TODO(goderbauer): when a11y is off this should return a one-off snapshot of
      // the a11y
      // tree.
      return null;
    }
  }

  private void releaseAccessibilityNodeProvider() {
    if (mAccessibilityNodeProvider != null) {
      mAccessibilityNodeProvider.release();
      mAccessibilityNodeProvider = null;
    }
  }

  // -------- Start: Mouse -------

  @Override
  @TargetApi(API_LEVELS.API_24)
  @RequiresApi(API_LEVELS.API_24)
  @NonNull
  public PointerIcon getSystemPointerIcon(int type) {
    return PointerIcon.getSystemIcon(getContext(), type);
  }

  // -------- End: Mouse -------

  // -------- Start: Keyboard -------

  @Override
  public BinaryMessenger getBinaryMessenger() {
    return this;
  }

  @Override
  public boolean onTextInputKeyEvent(@NonNull KeyEvent keyEvent) {
    return mTextInputPlugin.handleKeyEvent(keyEvent);
  }

  @Override
  public void redispatch(@NonNull KeyEvent keyEvent) {
    getRootView().dispatchKeyEvent(keyEvent);
  }

  // -------- End: Keyboard -------

  @Override
  @UiThread
  public TaskQueue makeBackgroundTaskQueue(TaskQueueOptions options) {
    return null;
  }

  @Override
  @UiThread
  public void send(String channel, ByteBuffer message) {
    send(channel, message, null);
  }

  @Override
  @UiThread
  public void send(String channel, ByteBuffer message, BinaryReply callback) {
    if (!isAttached()) {
      Log.d(TAG, "FlutterView.send called on a detached view, channel=" + channel);
      return;
    }
    mNativeView.send(channel, message, callback);
  }

  @Override
  @UiThread
  public void setMessageHandler(@NonNull String channel, @NonNull BinaryMessageHandler handler) {
    mNativeView.setMessageHandler(channel, handler);
  }

  @Override
  @UiThread
  public void setMessageHandler(
      @NonNull String channel,
      @NonNull BinaryMessageHandler handler,
      @NonNull TaskQueue taskQueue) {
    mNativeView.setMessageHandler(channel, handler, taskQueue);
  }

  /** Listener will be called on the Android UI thread once when Flutter renders the first frame. */
  public interface FirstFrameListener {
    void onFirstFrame();
  }

  @Override
  @NonNull
  public TextureRegistry.SurfaceTextureEntry createSurfaceTexture() {
    final SurfaceTexture surfaceTexture = new SurfaceTexture(0);
    return registerSurfaceTexture(surfaceTexture);
  }

  @Override
  @NonNull
  public ImageTextureEntry createImageTexture() {
    throw new UnsupportedOperationException("Image textures are not supported in this mode.");
  }

  @Override
  public SurfaceProducer createSurfaceProducer() {
    throw new UnsupportedOperationException(
        "SurfaceProducer textures are not supported in this mode.");
  }

  @Override
  @NonNull
  public TextureRegistry.SurfaceTextureEntry registerSurfaceTexture(
      @NonNull SurfaceTexture surfaceTexture) {
    surfaceTexture.detachFromGLContext();
    final SurfaceTextureRegistryEntry entry =
        new SurfaceTextureRegistryEntry(nextTextureId.getAndIncrement(), surfaceTexture);
    mNativeView.getFlutterJNI().registerTexture(entry.id(), entry.textureWrapper());
    return entry;
  }

  final class SurfaceTextureRegistryEntry implements TextureRegistry.SurfaceTextureEntry {
    private final long id;
    private final SurfaceTextureWrapper textureWrapper;
    private boolean released;

    SurfaceTextureRegistryEntry(long id, SurfaceTexture surfaceTexture) {
      this.id = id;
      this.textureWrapper = new SurfaceTextureWrapper(surfaceTexture);

      // 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());
    }

    private SurfaceTexture.OnFrameAvailableListener onFrameListener =
        new SurfaceTexture.OnFrameAvailableListener() {
          @Override
          public void onFrameAvailable(SurfaceTexture texture) {
            if (released || mNativeView == null) {
              // 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;
            }

            mNativeView
                .getFlutterJNI()
                .markTextureFrameAvailable(SurfaceTextureRegistryEntry.this.id);
          }
        };

    public SurfaceTextureWrapper textureWrapper() {
      return textureWrapper;
    }

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

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

    @Override
    public void release() {
      if (released) {
        return;
      }
      released = true;

      // The ordering of the next 3 calls is important:
      // First we remove the frame listener, then we release the SurfaceTexture, and only after we
      // unregister
      // the texture which actually deletes the GL texture.

      // Otherwise onFrameAvailableListener might be called after mNativeView==null
      // (https://github.com/flutter/flutter/issues/20951). See also the check in onFrameAvailable.
      surfaceTexture().setOnFrameAvailableListener(null);
      textureWrapper.release();
      mNativeView.getFlutterJNI().unregisterTexture(id);
    }
  }
}
