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

package io.flutter.embedding.android;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Insets;
import android.graphics.Rect;
import android.os.Build;
import android.os.LocaleList;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
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.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
import io.flutter.Log;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.renderer.FlutterRenderer;
import io.flutter.embedding.engine.renderer.FlutterUiDisplayListener;
import io.flutter.embedding.engine.renderer.RenderSurface;
import io.flutter.embedding.engine.systemchannels.SettingsChannel;
import io.flutter.plugin.editing.TextInputPlugin;
import io.flutter.plugin.platform.PlatformViewsController;
import io.flutter.view.AccessibilityBridge;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

/**
 * Displays a Flutter UI on an Android device.
 *
 * <p>A {@code FlutterView}'s UI is painted by a corresponding {@link FlutterEngine}.
 *
 * <p>A {@code FlutterView} can operate in 2 different {@link
 * io.flutter.embedding.android.RenderMode}s:
 *
 * <ol>
 *   <li>{@link io.flutter.embedding.android.RenderMode#surface}, which paints a Flutter UI to a
 *       {@link android.view.SurfaceView}. This mode has the best performance, but a {@code
 *       FlutterView} in this mode cannot be positioned between 2 other Android {@code View}s in the
 *       z-index, nor can it be animated/transformed. Unless the special capabilities of a {@link
 *       android.graphics.SurfaceTexture} are required, developers should strongly prefer this
 *       render mode.
 *   <li>{@link io.flutter.embedding.android.RenderMode#texture}, which paints a Flutter UI to a
 *       {@link android.graphics.SurfaceTexture}. This mode is not as performant as {@link
 *       io.flutter.embedding.android.RenderMode#surface}, but a {@code FlutterView} in this mode
 *       can be animated and transformed, as well as positioned in the z-index between 2+ other
 *       Android {@code Views}. Unless the special capabilities of a {@link
 *       android.graphics.SurfaceTexture} are required, developers should strongly prefer the {@link
 *       io.flutter.embedding.android.RenderMode#surface} render mode.
 * </ol>
 *
 * See <a>https://source.android.com/devices/graphics/arch-tv#surface_or_texture</a> for more
 * information comparing {@link android.view.SurfaceView} and {@link android.view.TextureView}.
 */
public class FlutterView extends FrameLayout {
  private static final String TAG = "FlutterView";

  // Internal view hierarchy references.
  @Nullable private FlutterSurfaceView flutterSurfaceView;
  @Nullable private FlutterTextureView flutterTextureView;
  @Nullable private RenderSurface renderSurface;
  private final Set<FlutterUiDisplayListener> flutterUiDisplayListeners = new HashSet<>();
  private boolean isFlutterUiDisplayed;

  // Connections to a Flutter execution context.
  @Nullable private FlutterEngine flutterEngine;

  @NonNull
  private final Set<FlutterEngineAttachmentListener> flutterEngineAttachmentListeners =
      new HashSet<>();

  // Components that process various types of Android View input and events,
  // possibly storing intermediate state, and communicating those events to Flutter.
  //
  // These components essentially add some additional behavioral logic on top of
  // existing, stateless system channels, e.g., KeyEventChannel, TextInputChannel, etc.
  @Nullable private TextInputPlugin textInputPlugin;
  @Nullable private AndroidKeyProcessor androidKeyProcessor;
  @Nullable private AndroidTouchProcessor androidTouchProcessor;
  @Nullable private AccessibilityBridge accessibilityBridge;

  // Directly implemented View behavior that communicates with Flutter.
  private final FlutterRenderer.ViewportMetrics viewportMetrics =
      new FlutterRenderer.ViewportMetrics();

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

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

          for (FlutterUiDisplayListener listener : flutterUiDisplayListeners) {
            listener.onFlutterUiDisplayed();
          }
        }

        @Override
        public void onFlutterUiNoLongerDisplayed() {
          isFlutterUiDisplayed = false;

          for (FlutterUiDisplayListener listener : flutterUiDisplayListeners) {
            listener.onFlutterUiNoLongerDisplayed();
          }
        }
      };

  /**
   * Constructs a {@code FlutterView} programmatically, without any XML attributes.
   *
   * <p>
   *
   * <ul>
   *   <li>A {@link FlutterSurfaceView} is used to render the Flutter UI.
   *   <li>{@code transparencyMode} defaults to {@link TransparencyMode#opaque}.
   * </ul>
   *
   * {@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} to be
   * compatible with {@link PlatformViewsController}.
   */
  public FlutterView(@NonNull Context context) {
    this(context, null, new FlutterSurfaceView(context));
  }

  /**
   * Deprecated - use {@link #FlutterView(Context, FlutterSurfaceView)} or {@link
   * #FlutterView(Context, FlutterTextureView)} instead.
   */
  @Deprecated
  public FlutterView(@NonNull Context context, @NonNull RenderMode renderMode) {
    super(context, null);

    if (renderMode == RenderMode.surface) {
      flutterSurfaceView = new FlutterSurfaceView(context);
      renderSurface = flutterSurfaceView;
    } else {
      flutterTextureView = new FlutterTextureView(context);
      renderSurface = flutterTextureView;
    }

    init();
  }

  /**
   * Deprecated - use {@link #FlutterView(Context, FlutterSurfaceView)} or {@link
   * #FlutterView(Context, FlutterTextureView)} instead, and configure the incoming {@code
   * FlutterSurfaceView} or {@code FlutterTextureView} for transparency as desired.
   *
   * <p>Constructs a {@code FlutterView} programmatically, without any XML attributes, uses a {@link
   * FlutterSurfaceView} to render the Flutter UI, and allows selection of a {@code
   * transparencyMode}.
   *
   * <p>{@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} to be
   * compatible with {@link PlatformViewsController}.
   */
  @Deprecated
  public FlutterView(@NonNull Context context, @NonNull TransparencyMode transparencyMode) {
    this(
        context,
        null,
        new FlutterSurfaceView(context, transparencyMode == TransparencyMode.transparent));
  }

  /**
   * Constructs a {@code FlutterView} programmatically, without any XML attributes, uses the given
   * {@link FlutterSurfaceView} to render the Flutter UI, and allows selection of a {@code
   * transparencyMode}.
   *
   * <p>{@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} to be
   * compatible with {@link PlatformViewsController}.
   */
  public FlutterView(@NonNull Context context, @NonNull FlutterSurfaceView flutterSurfaceView) {
    this(context, null, flutterSurfaceView);
  }

  /**
   * Constructs a {@code FlutterView} programmatically, without any XML attributes, uses the given
   * {@link FlutterTextureView} to render the Flutter UI, and allows selection of a {@code
   * transparencyMode}.
   *
   * <p>{@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} to be
   * compatible with {@link PlatformViewsController}.
   */
  public FlutterView(@NonNull Context context, @NonNull FlutterTextureView flutterTextureView) {
    this(context, null, flutterTextureView);
  }

  /**
   * Constructs a {@code FlutterView} in an XML-inflation-compliant manner.
   *
   * <p>{@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} to be
   * compatible with {@link PlatformViewsController}.
   */
  // TODO(mattcarroll): expose renderMode in XML when build system supports R.attr
  public FlutterView(@NonNull Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, new FlutterSurfaceView(context));
  }

  /**
   * Deprecated - use {@link #FlutterView(Context, FlutterSurfaceView)} or {@link
   * #FlutterView(Context, FlutterTextureView)} instead, and configure the incoming {@code
   * FlutterSurfaceView} or {@code FlutterTextureView} for transparency as desired.
   */
  @Deprecated
  public FlutterView(
      @NonNull Context context,
      @NonNull RenderMode renderMode,
      @NonNull TransparencyMode transparencyMode) {
    super(context, null);

    if (renderMode == RenderMode.surface) {
      flutterSurfaceView =
          new FlutterSurfaceView(context, transparencyMode == TransparencyMode.transparent);
      renderSurface = flutterSurfaceView;
    } else {
      flutterTextureView = new FlutterTextureView(context);
      renderSurface = flutterTextureView;
    }

    init();
  }

  private FlutterView(
      @NonNull Context context,
      @Nullable AttributeSet attrs,
      @NonNull FlutterSurfaceView flutterSurfaceView) {
    super(context, attrs);

    this.flutterSurfaceView = flutterSurfaceView;
    this.renderSurface = flutterSurfaceView;

    init();
  }

  private FlutterView(
      @NonNull Context context,
      @Nullable AttributeSet attrs,
      @NonNull FlutterTextureView flutterTextureView) {
    super(context, attrs);

    this.flutterTextureView = flutterTextureView;
    this.renderSurface = flutterTextureView;

    init();
  }

  private void init() {
    Log.v(TAG, "Initializing FlutterView");

    if (flutterSurfaceView != null) {
      Log.v(TAG, "Internally using a FlutterSurfaceView.");
      addView(flutterSurfaceView);
    } else {
      Log.v(TAG, "Internally using a FlutterTextureView.");
      addView(flutterTextureView);
    }

    // FlutterView needs to be focusable so that the InputMethodManager can interact with it.
    setFocusable(true);
    setFocusableInTouchMode(true);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS);
    }
  }

  /**
   * Returns true if an attached {@link FlutterEngine} has rendered at least 1 frame to this {@code
   * FlutterView}.
   *
   * <p>Returns false if no {@link FlutterEngine} is attached.
   *
   * <p>This flag is specific to a given {@link FlutterEngine}. The following hypothetical timeline
   * demonstrates how this flag changes over time.
   *
   * <ol>
   *   <li>{@code flutterEngineA} is attached to this {@code FlutterView}: returns false
   *   <li>{@code flutterEngineA} renders its first frame to this {@code FlutterView}: returns true
   *   <li>{@code flutterEngineA} is detached from this {@code FlutterView}: returns false
   *   <li>{@code flutterEngineB} is attached to this {@code FlutterView}: returns false
   *   <li>{@code flutterEngineB} renders its first frame to this {@code FlutterView}: returns true
   * </ol>
   */
  public boolean hasRenderedFirstFrame() {
    return isFlutterUiDisplayed;
  }

  /**
   * Adds the given {@code listener} to this {@code FlutterView}, to be notified upon Flutter's
   * first rendered frame.
   */
  public void addOnFirstFrameRenderedListener(@NonNull FlutterUiDisplayListener listener) {
    flutterUiDisplayListeners.add(listener);
  }

  /**
   * Removes the given {@code listener}, which was previously added with {@link
   * #addOnFirstFrameRenderedListener(FlutterUiDisplayListener)}.
   */
  public void removeOnFirstFrameRenderedListener(@NonNull FlutterUiDisplayListener listener) {
    flutterUiDisplayListeners.remove(listener);
  }

  // ------- Start: Process View configuration that Flutter cares about. ------
  /**
   * Sends relevant configuration data from Android to Flutter when the Android {@link
   * Configuration} changes.
   *
   * <p>The Android {@link Configuration} might change as a result of device orientation change,
   * device language change, device text scale factor change, etc.
   */
  @Override
  protected void onConfigurationChanged(@NonNull Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // We've observed on Android Q that going to the background, changing
    // orientation, and bringing the app back to foreground results in a sequence
    // of detatch from flutterEngine, onConfigurationChanged, followed by attach
    // to flutterEngine.
    // No-op here so that we avoid NPE; these channels will get notified once
    // the activity or fragment tell the view to attach to the Flutter engine
    // again (e.g. in onStart).
    if (flutterEngine != null) {
      Log.v(TAG, "Configuration changed. Sending locales and user settings to Flutter.");
      sendLocalesToFlutter(newConfig);
      sendUserSettingsToFlutter();
    }
  }

  /**
   * Invoked when this {@code FlutterView} changes size, including upon initial measure.
   *
   * <p>The initial measure reports an {@code oldWidth} and {@code oldHeight} of zero.
   *
   * <p>Flutter cares about the width and height of the view that displays it on the host platform.
   * Therefore, when this method is invoked, the new width and height are communicated to Flutter as
   * the "physical size" of the view that displays Flutter's UI.
   */
  @Override
  protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
    super.onSizeChanged(width, height, oldWidth, oldHeight);
    Log.v(
        TAG,
        "Size changed. Sending Flutter new viewport metrics. FlutterView was "
            + oldWidth
            + " x "
            + oldHeight
            + ", it is now "
            + width
            + " x "
            + height);
    viewportMetrics.width = width;
    viewportMetrics.height = height;
    sendViewportMetricsToFlutter();
  }

  // TODO(garyq): Add support for notch cutout API: https://github.com/flutter/flutter/issues/56592
  // 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();
    }
  }

  /**
   * Invoked when Android's desired window insets change, i.e., padding.
   *
   * <p>Flutter does not use a standard {@code View} hierarchy and therefore Flutter is unaware of
   * these insets. Therefore, this method calculates the viewport metrics that Flutter should use
   * and then sends those metrics to Flutter.
   *
   * <p>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.
   */
  @Override
  @TargetApi(20)
  @RequiresApi(20)
  // 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.
  @SuppressLint({"InlinedApi", "NewApi"})
  @NonNull
  public final WindowInsets onApplyWindowInsets(@NonNull WindowInsets insets) {
    WindowInsets newInsets = super.onApplyWindowInsets(insets);

    boolean statusBarHidden = (SYSTEM_UI_FLAG_FULLSCREEN & getWindowSystemUiVisibility()) != 0;
    boolean navigationBarHidden =
        (SYSTEM_UI_FLAG_HIDE_NAVIGATION & getWindowSystemUiVisibility()) != 0;
    // We zero the left and/or right sides to prevent the padding the
    // navigation bar would have caused.
    ZeroSides zeroSides = ZeroSides.NONE;
    if (navigationBarHidden) {
      zeroSides = calculateShouldZeroSides();
    }

    // Status bar (top) and left/right system insets should partially obscure the content (padding).
    viewportMetrics.paddingTop = statusBarHidden ? 0 : insets.getSystemWindowInsetTop();
    viewportMetrics.paddingRight =
        zeroSides == ZeroSides.RIGHT || zeroSides == ZeroSides.BOTH
            ? 0
            : insets.getSystemWindowInsetRight();
    viewportMetrics.paddingBottom = 0;
    viewportMetrics.paddingLeft =
        zeroSides == ZeroSides.LEFT || zeroSides == ZeroSides.BOTH
            ? 0
            : insets.getSystemWindowInsetLeft();

    // Bottom system inset (keyboard) should adjust scrollable bottom edge (inset).
    viewportMetrics.viewInsetTop = 0;
    viewportMetrics.viewInsetRight = 0;
    viewportMetrics.viewInsetBottom =
        navigationBarHidden
            ? guessBottomKeyboardInset(insets)
            : insets.getSystemWindowInsetBottom();
    viewportMetrics.viewInsetLeft = 0;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
      Insets systemGestureInsets = insets.getSystemGestureInsets();
      viewportMetrics.systemGestureInsetTop = systemGestureInsets.top;
      viewportMetrics.systemGestureInsetRight = systemGestureInsets.right;
      viewportMetrics.systemGestureInsetBottom = systemGestureInsets.bottom;
      viewportMetrics.systemGestureInsetLeft = systemGestureInsets.left;
    }

    Log.v(
        TAG,
        "Updating window insets (onApplyWindowInsets()):\n"
            + "Status bar insets: Top: "
            + viewportMetrics.paddingTop
            + ", Left: "
            + viewportMetrics.paddingLeft
            + ", Right: "
            + viewportMetrics.paddingRight
            + "\n"
            + "Keyboard insets: Bottom: "
            + viewportMetrics.viewInsetBottom
            + ", Left: "
            + viewportMetrics.viewInsetLeft
            + ", Right: "
            + viewportMetrics.viewInsetRight
            + "System Gesture Insets - Left: "
            + viewportMetrics.systemGestureInsetLeft
            + ", Top: "
            + viewportMetrics.systemGestureInsetTop
            + ", Right: "
            + viewportMetrics.systemGestureInsetRight
            + ", Bottom: "
            + viewportMetrics.viewInsetBottom);

    sendViewportMetricsToFlutter();

    return newInsets;
  }

  /**
   * Invoked when Android's desired window insets change, i.e., padding.
   *
   * <p>{@code fitSystemWindows} is an earlier version of {@link
   * #onApplyWindowInsets(WindowInsets)}. See that method for more details about how window insets
   * relate to Flutter.
   */
  @Override
  @SuppressWarnings("deprecation")
  protected boolean fitSystemWindows(@NonNull Rect insets) {
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
      // Status bar, left/right system insets partially obscure content (padding).
      viewportMetrics.paddingTop = insets.top;
      viewportMetrics.paddingRight = insets.right;
      viewportMetrics.paddingBottom = 0;
      viewportMetrics.paddingLeft = insets.left;

      // Bottom system inset (keyboard) should adjust scrollable bottom edge (inset).
      viewportMetrics.viewInsetTop = 0;
      viewportMetrics.viewInsetRight = 0;
      viewportMetrics.viewInsetBottom = insets.bottom;
      viewportMetrics.viewInsetLeft = 0;

      Log.v(
          TAG,
          "Updating window insets (fitSystemWindows()):\n"
              + "Status bar insets: Top: "
              + viewportMetrics.paddingTop
              + ", Left: "
              + viewportMetrics.paddingLeft
              + ", Right: "
              + viewportMetrics.paddingRight
              + "\n"
              + "Keyboard insets: Bottom: "
              + viewportMetrics.viewInsetBottom
              + ", Left: "
              + viewportMetrics.viewInsetLeft
              + ", Right: "
              + viewportMetrics.viewInsetRight);

      sendViewportMetricsToFlutter();
      return true;
    } else {
      return super.fitSystemWindows(insets);
    }
  }
  // ------- End: Process View configuration that Flutter cares about. --------

  // -------- Start: Process UI I/O that Flutter cares about. -------
  /**
   * Creates an {@link InputConnection} to work with a {@link
   * android.view.inputmethod.InputMethodManager}.
   *
   * <p>Any {@code View} that can take focus or process text input must implement this method by
   * returning a non-null {@code InputConnection}. Flutter may render one or many focusable and
   * text-input widgets, therefore {@code FlutterView} must support an {@code InputConnection}.
   *
   * <p>The {@code InputConnection} returned from this method comes from a {@link TextInputPlugin},
   * which is owned by this {@code FlutterView}. A {@link TextInputPlugin} exists to encapsulate the
   * nuances of input communication, rather than spread that logic throughout this {@code
   * FlutterView}.
   */
  @Override
  @Nullable
  public InputConnection onCreateInputConnection(@NonNull EditorInfo outAttrs) {
    if (!isAttachedToFlutterEngine()) {
      return super.onCreateInputConnection(outAttrs);
    }

    return textInputPlugin.createInputConnection(this, outAttrs);
  }

  /**
   * Allows a {@code View} that is not currently the input connection target to invoke commands on
   * the {@link android.view.inputmethod.InputMethodManager}, which is otherwise disallowed.
   *
   * <p>Returns true to allow non-input-connection-targets to invoke methods on {@code
   * InputMethodManager}, or false to exclusively allow the input connection target to invoke such
   * methods.
   */
  @Override
  public boolean checkInputConnectionProxy(View view) {
    return flutterEngine != null
        ? flutterEngine.getPlatformViewsController().checkInputConnectionProxy(view)
        : super.checkInputConnectionProxy(view);
  }

  /**
   * Invoked when key is released.
   *
   * <p>This method is typically invoked in response to the release of a physical keyboard key or a
   * D-pad button. It is generally not invoked when a virtual software keyboard is used, though a
   * software keyboard may choose to invoke this method in some situations.
   *
   * <p>{@link KeyEvent}s are sent from Android to Flutter. {@link AndroidKeyProcessor} may do some
   * additional work with the given {@link KeyEvent}, e.g., combine this {@code keyCode} with the
   * previous {@code keyCode} to generate a unicode combined character.
   */
  @Override
  public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
    if (!isAttachedToFlutterEngine()) {
      return super.onKeyUp(keyCode, event);
    }

    androidKeyProcessor.onKeyUp(event);
    return super.onKeyUp(keyCode, event);
  }

  /**
   * Invoked when key is pressed.
   *
   * <p>This method is typically invoked in response to the press of a physical keyboard key or a
   * D-pad button. It is generally not invoked when a virtual software keyboard is used, though a
   * software keyboard may choose to invoke this method in some situations.
   *
   * <p>{@link KeyEvent}s are sent from Android to Flutter. {@link AndroidKeyProcessor} may do some
   * additional work with the given {@link KeyEvent}, e.g., combine this {@code keyCode} with the
   * previous {@code keyCode} to generate a unicode combined character.
   */
  @Override
  public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
    if (!isAttachedToFlutterEngine()) {
      return super.onKeyDown(keyCode, event);
    }

    androidKeyProcessor.onKeyDown(event);
    return super.onKeyDown(keyCode, event);
  }

  /**
   * Invoked by Android when a user touch event occurs.
   *
   * <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 onTouchEvent(@NonNull MotionEvent event) {
    if (!isAttachedToFlutterEngine()) {
      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);
  }

  /**
   * 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(@NonNull MotionEvent event) {
    boolean handled =
        isAttachedToFlutterEngine() && androidTouchProcessor.onGenericMotionEvent(event);
    return handled ? true : super.onGenericMotionEvent(event);
  }

  /**
   * Invoked by Android when a hover-compliant input system causes a hover event.
   *
   * <p>An example of hover events is a stylus sitting near an Android screen. As the stylus moves
   * from outside a {@code View} to hover over a {@code View}, or move around within a {@code View},
   * or moves from over a {@code View} to outside a {@code View}, a corresponding {@link
   * MotionEvent} is reported via this method.
   *
   * <p>Hover events can be used for accessibility touch exploration and therefore are processed
   * here for accessibility purposes.
   */
  @Override
  public boolean onHoverEvent(@NonNull MotionEvent event) {
    if (!isAttachedToFlutterEngine()) {
      return super.onHoverEvent(event);
    }

    boolean handled = accessibilityBridge.onAccessibilityHoverEvent(event);
    if (!handled) {
      // TODO(ianh): Expose hover events to the platform,
      // implementing ADD, REMOVE, etc.
    }
    return handled;
  }
  // -------- End: Process UI I/O that Flutter cares about. ---------

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

  // 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 (!flutterEngine.getRenderer().isSoftwareRenderingEnabled()) {
      setWillNotDraw(!(isAccessibilityEnabled || isTouchExplorationEnabled));
    } else {
      setWillNotDraw(false);
    }
  }
  // -------- End: Accessibility ---------

  /**
   * Connects this {@code FlutterView} to the given {@link FlutterEngine}.
   *
   * <p>This {@code FlutterView} will begin rendering the UI painted by the given {@link
   * FlutterEngine}. This {@code FlutterView} will also begin forwarding interaction events from
   * this {@code FlutterView} to the given {@link FlutterEngine}, e.g., user touch events,
   * accessibility events, keyboard events, and others.
   *
   * <p>See {@link #detachFromFlutterEngine()} for information on how to detach from a {@link
   * FlutterEngine}.
   */
  public void attachToFlutterEngine(@NonNull FlutterEngine flutterEngine) {
    Log.v(TAG, "Attaching to a FlutterEngine: " + flutterEngine);
    if (isAttachedToFlutterEngine()) {
      if (flutterEngine == this.flutterEngine) {
        // We are already attached to this FlutterEngine
        Log.v(TAG, "Already attached to this engine. Doing nothing.");
        return;
      }

      // Detach from a previous FlutterEngine so we can attach to this new one.
      Log.v(
          TAG,
          "Currently attached to a different engine. Detaching and then attaching"
              + " to new engine.");
      detachFromFlutterEngine();
    }

    this.flutterEngine = flutterEngine;

    // Instruct our FlutterRenderer that we are now its designated RenderSurface.
    FlutterRenderer flutterRenderer = this.flutterEngine.getRenderer();
    isFlutterUiDisplayed = flutterRenderer.isDisplayingFlutterUi();
    renderSurface.attachToRenderer(flutterRenderer);
    flutterRenderer.addIsDisplayingFlutterUiListener(flutterUiDisplayListener);

    // Initialize various components that know how to process Android View I/O
    // in a way that Flutter understands.
    textInputPlugin =
        new TextInputPlugin(
            this,
            this.flutterEngine.getTextInputChannel(),
            this.flutterEngine.getPlatformViewsController());
    androidKeyProcessor =
        new AndroidKeyProcessor(this.flutterEngine.getKeyEventChannel(), textInputPlugin);
    androidTouchProcessor = new AndroidTouchProcessor(this.flutterEngine.getRenderer());
    accessibilityBridge =
        new AccessibilityBridge(
            this,
            flutterEngine.getAccessibilityChannel(),
            (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE),
            getContext().getContentResolver(),
            this.flutterEngine.getPlatformViewsController());
    accessibilityBridge.setOnAccessibilityChangeListener(onAccessibilityChangeListener);
    resetWillNotDraw(
        accessibilityBridge.isAccessibilityEnabled(),
        accessibilityBridge.isTouchExplorationEnabled());

    // Connect AccessibilityBridge to the PlatformViewsController within the FlutterEngine.
    // This allows platform Views to hook into Flutter's overall accessibility system.
    this.flutterEngine.getPlatformViewsController().attachAccessibilityBridge(accessibilityBridge);

    // Inform the Android framework that it should retrieve a new InputConnection
    // now that an engine is attached.
    // TODO(mattcarroll): once this is proven to work, move this line ot TextInputPlugin
    textInputPlugin.getInputMethodManager().restartInput(this);

    // Push View and Context related information from Android to Flutter.
    sendUserSettingsToFlutter();
    sendLocalesToFlutter(getResources().getConfiguration());
    sendViewportMetricsToFlutter();

    flutterEngine.getPlatformViewsController().attachToView(this);

    // Notify engine attachment listeners of the attachment.
    for (FlutterEngineAttachmentListener listener : flutterEngineAttachmentListeners) {
      listener.onFlutterEngineAttachedToFlutterView(flutterEngine);
    }

    // If the first frame has already been rendered, notify all first frame listeners.
    // Do this after all other initialization so that listeners don't inadvertently interact
    // with a FlutterView that is only partially attached to a FlutterEngine.
    if (isFlutterUiDisplayed) {
      flutterUiDisplayListener.onFlutterUiDisplayed();
    }
  }

  /**
   * Disconnects this {@code FlutterView} from a previously attached {@link FlutterEngine}.
   *
   * <p>This {@code FlutterView} will clear its UI and stop forwarding all events to the
   * previously-attached {@link FlutterEngine}. This includes touch events, accessibility events,
   * keyboard events, and others.
   *
   * <p>See {@link #attachToFlutterEngine(FlutterEngine)} for information on how to attach a {@link
   * FlutterEngine}.
   */
  public void detachFromFlutterEngine() {
    Log.v(TAG, "Detaching from a FlutterEngine: " + flutterEngine);
    if (!isAttachedToFlutterEngine()) {
      Log.v(TAG, "Not attached to an engine. Doing nothing.");
      return;
    }

    // Notify engine attachment listeners of the detachment.
    for (FlutterEngineAttachmentListener listener : flutterEngineAttachmentListeners) {
      listener.onFlutterEngineDetachedFromFlutterView();
    }

    flutterEngine.getPlatformViewsController().detachFromView();

    // Disconnect the FlutterEngine's PlatformViewsController from the AccessibilityBridge.
    flutterEngine.getPlatformViewsController().detachAccessibiltyBridge();

    // Disconnect and clean up the AccessibilityBridge.
    accessibilityBridge.release();
    accessibilityBridge = null;

    // Inform the Android framework that it should retrieve a new InputConnection
    // now that the engine is detached. The new InputConnection will be null, which
    // signifies that this View does not process input (until a new engine is attached).
    // TODO(mattcarroll): once this is proven to work, move this line ot TextInputPlugin
    textInputPlugin.getInputMethodManager().restartInput(this);
    textInputPlugin.destroy();

    // Instruct our FlutterRenderer that we are no longer interested in being its RenderSurface.
    FlutterRenderer flutterRenderer = flutterEngine.getRenderer();
    isFlutterUiDisplayed = false;
    flutterRenderer.removeIsDisplayingFlutterUiListener(flutterUiDisplayListener);
    flutterRenderer.stopRenderingToSurface();
    flutterRenderer.setSemanticsEnabled(false);
    renderSurface.detachFromRenderer();
    flutterEngine = null;
  }

  /** Returns true if this {@code FlutterView} is currently attached to a {@link FlutterEngine}. */
  @VisibleForTesting
  public boolean isAttachedToFlutterEngine() {
    return flutterEngine != null
        && flutterEngine.getRenderer() == renderSurface.getAttachedRenderer();
  }

  /**
   * Returns the {@link FlutterEngine} to which this {@code FlutterView} is currently attached, or
   * null if this {@code FlutterView} is not currently attached to a {@link FlutterEngine}.
   */
  @VisibleForTesting
  @Nullable
  public FlutterEngine getAttachedFlutterEngine() {
    return flutterEngine;
  }

  /**
   * Adds a {@link FlutterEngineAttachmentListener}, which is notifed whenever this {@code
   * FlutterView} attached to/detaches from a {@link FlutterEngine}.
   */
  @VisibleForTesting
  public void addFlutterEngineAttachmentListener(
      @NonNull FlutterEngineAttachmentListener listener) {
    flutterEngineAttachmentListeners.add(listener);
  }

  /**
   * Removes a {@link FlutterEngineAttachmentListener} that was previously added with {@link
   * #addFlutterEngineAttachmentListener(FlutterEngineAttachmentListener)}.
   */
  @VisibleForTesting
  public void removeFlutterEngineAttachmentListener(
      @NonNull FlutterEngineAttachmentListener listener) {
    flutterEngineAttachmentListeners.remove(listener);
  }

  /**
   * Send the current {@link Locale} configuration to Flutter.
   *
   * <p>FlutterEngine must be non-null when this method is invoked.
   */
  @SuppressWarnings("deprecation")
  private void sendLocalesToFlutter(@NonNull Configuration config) {
    List<Locale> locales = new ArrayList<>();
    if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
      LocaleList localeList = config.getLocales();
      int localeCount = localeList.size();
      for (int index = 0; index < localeCount; ++index) {
        Locale locale = localeList.get(index);
        locales.add(locale);
      }
    } else {
      locales.add(config.locale);
    }

    Locale platformResolvedLocale = null;
    if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
      List<Locale.LanguageRange> languageRanges = new ArrayList<>();
      LocaleList localeList = config.getLocales();
      int localeCount = localeList.size();
      for (int index = 0; index < localeCount; ++index) {
        Locale locale = localeList.get(index);
        languageRanges.add(new Locale.LanguageRange(locale.toLanguageTag()));
      }
      // TODO(garyq) implement a real locale resolution.
      platformResolvedLocale =
          Locale.lookup(languageRanges, Arrays.asList(Locale.getAvailableLocales()));
    }

    flutterEngine.getLocalizationChannel().sendLocales(locales, platformResolvedLocale);
  }

  /**
   * Send various user preferences of this Android device to Flutter.
   *
   * <p>For example, sends the user's "text scale factor" preferences, as well as the user's clock
   * format preference.
   *
   * <p>FlutterEngine must be non-null when this method is invoked.
   */
  @VisibleForTesting
  /* package */ void sendUserSettingsToFlutter() {
    // 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;

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

  // TODO(mattcarroll): consider introducing a system channel for this communication instead of JNI
  private void sendViewportMetricsToFlutter() {
    if (!isAttachedToFlutterEngine()) {
      Log.w(
          TAG,
          "Tried to send viewport metrics from Android to Flutter but this "
              + "FlutterView was not attached to a FlutterEngine.");
      return;
    }

    viewportMetrics.devicePixelRatio = getResources().getDisplayMetrics().density;
    flutterEngine.getRenderer().setViewportMetrics(viewportMetrics);
  }

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

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

  /**
   * Render modes for a {@link FlutterView}.
   *
   * <p>Deprecated - please use {@link io.flutter.embedding.android.RenderMode} instead.
   */
  @Deprecated()
  public enum RenderMode {
    /**
     * {@code RenderMode}, which paints a Flutter UI to a {@link android.view.SurfaceView}. This
     * mode has the best performance, but a {@code FlutterView} in this mode cannot be positioned
     * between 2 other Android {@code View}s in the z-index, nor can it be animated/transformed.
     * Unless the special capabilities of a {@link android.graphics.SurfaceTexture} are required,
     * developers should strongly prefer this render mode.
     */
    surface,
    /**
     * {@code RenderMode}, which paints a Flutter UI to a {@link android.graphics.SurfaceTexture}.
     * This mode is not as performant as {@link RenderMode#surface}, but a {@code FlutterView} in
     * this mode can be animated and transformed, as well as positioned in the z-index between 2+
     * other Android {@code Views}. Unless the special capabilities of a {@link
     * android.graphics.SurfaceTexture} are required, developers should strongly prefer the {@link
     * RenderMode#surface} render mode.
     */
    texture
  }

  /**
   * Transparency mode for a {@code FlutterView}.
   *
   * <p>Deprecated - please use {@link io.flutter.embedding.android.TransparencyMode} instead.
   *
   * <p>{@code TransparencyMode} impacts the visual behavior and performance of a {@link
   * FlutterSurfaceView}, which is displayed when a {@code FlutterView} uses {@link
   * RenderMode#surface}.
   *
   * <p>{@code TransparencyMode} does not impact {@link FlutterTextureView}, which is displayed when
   * a {@code FlutterView} uses {@link RenderMode#texture}, because a {@link FlutterTextureView}
   * automatically comes with transparency.
   */
  @Deprecated
  public enum TransparencyMode {
    /**
     * Renders a {@code FlutterView} without any transparency. This affects {@code FlutterView}s in
     * {@link io.flutter.embedding.android.RenderMode#surface} by introducing a base color of black,
     * and places the {@link FlutterSurfaceView}'s {@code Window} behind all other content.
     *
     * <p>In {@link io.flutter.embedding.android.RenderMode#surface}, this mode is the most
     * performant and is a good choice for fullscreen Flutter UIs that will not undergo {@code
     * Fragment} transactions. If this mode is used within a {@code Fragment}, and that {@code
     * Fragment} is replaced by another one, a brief black flicker may be visible during the switch.
     */
    opaque,
    /**
     * Renders a {@code FlutterView} with transparency. This affects {@code FlutterView}s in {@link
     * io.flutter.embedding.android.RenderMode#surface} by allowing background transparency, and
     * places the {@link FlutterSurfaceView}'s {@code Window} on top of all other content.
     *
     * <p>In {@link io.flutter.embedding.android.RenderMode#surface}, this mode is less performant
     * than {@link #opaque}, but this mode avoids the black flicker problem that {@link #opaque} has
     * when going through {@code Fragment} transactions. Consider using this {@code
     * TransparencyMode} if you intend to switch {@code Fragment}s at runtime that contain a Flutter
     * UI.
     */
    transparent
  }

  /**
   * Listener that is notified when a {@link FlutterEngine} is attached to/detached from a given
   * {@code FlutterView}.
   */
  @VisibleForTesting
  public interface FlutterEngineAttachmentListener {
    /** The given {@code engine} has been attached to the associated {@code FlutterView}. */
    void onFlutterEngineAttachedToFlutterView(@NonNull FlutterEngine engine);

    /**
     * A previously attached {@link FlutterEngine} has been detached from the associated {@code
     * FlutterView}.
     */
    void onFlutterEngineDetachedFromFlutterView();
  }
}
