// 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 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.Rect;
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 >= Build.VERSION_CODES.N) {
      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);
    }

    // TODO(abarth): This version check might not be effective in some
    // versions of Android that statically compile code and will be upset
    // at the lack of |requestUnbufferedDispatch|. Instead, we should factor
    // version-dependent code into separate classes for each supported
    // version and dispatch dynamically.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      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 >= 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.
  @TargetApi(20)
  @RequiresApi(20)
  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
  @TargetApi(20)
  @RequiresApi(20)
  @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 == Build.VERSION_CODES.Q) {
      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 >= Build.VERSION_CODES.R) {
      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);
  }

  @Override
  @SuppressWarnings("deprecation")
  protected boolean fitSystemWindows(Rect insets) {
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
      // Status bar, left/right system insets partially obscure content (padding).
      mMetrics.physicalViewPaddingTop = insets.top;
      mMetrics.physicalViewPaddingRight = insets.right;
      mMetrics.physicalViewPaddingBottom = 0;
      mMetrics.physicalViewPaddingLeft = insets.left;

      // Bottom system inset (keyboard) should adjust scrollable bottom edge (inset).
      mMetrics.physicalViewInsetTop = 0;
      mMetrics.physicalViewInsetRight = 0;
      mMetrics.physicalViewInsetBottom = insets.bottom;
      mMetrics.physicalViewInsetLeft = 0;
      updateViewportMetrics();
      return true;
    } else {
      return super.fitSystemWindows(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(Build.VERSION_CODES.N)
  @RequiresApi(Build.VERSION_CODES.N)
  @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);

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // 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());
      } else {
        // Android documentation states that the listener can be called on an arbitrary thread.
        // But in practice, versions of Android that predate the newer API will call the listener
        // on the thread where the SurfaceTexture was constructed.
        this.surfaceTexture().setOnFrameAvailableListener(onFrameListener);
      }
    }

    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;
    }

    @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);
    }
  }
}
