Repository: flutter/flutter
File: engine/src/flutter/shell/platform/android/io/flutter/embedding/android/FlutterView.java (Java)

Code before:

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    widthMode = MeasureSpec.getMode(widthMeasureSpec);
    heightMode = MeasureSpec.getMode(heightMeasureSpec);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  }

  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;
    viewportMetrics.physicalTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
    flutterEngine.getRenderer().setViewportMetrics(viewportMetrics);
  }

  @Override
  public void onProvideAutofillVirtualStructure(@NonNull ViewStructure structure, int flags) {
    super.onProvideAutofillVirtualStructure(structure, flags);
    if(textInputPlugin != null) {
      textInputPlugin.onProvideAutofillVirtualStructure(structure, flags);
    }
  }

  @Override
  public void autofill(@NonNull SparseArray<AutofillValue> values) {
    if(textInputPlugin != null) {
      textInputPlugin.autofill(values);
    }
  }

  @Override
  public void setVisibility(int visibility) {
    super.setVisibility(visibility);
    // For `FlutterSurfaceView`, setting visibility to the current `FlutterView` will not take
    // effect since it is not in the view tree. So override this method and set the surfaceView.
    // See https://github.com/flutter/flutter/issues/105203
    if (renderSurface instanceof FlutterSurfaceView) {
      ((FlutterSurfaceView) renderSurface).setVisibility(visibility);
    }
  }

  /**
   * Allow access to the viewport metrics so that tests can set them to be valid with nonzero
   * dimensions.

Review comment (bug):
I’m not very familiar with the engine itself, only with the Android ecosystem, but from my perspective this solves only half of the problem. It prevents the app from crashing, but the box will never be shown to the user.



Code after:
        .setTextScaleFactor(getResources().getConfiguration().fontScale)
        .setDisplayMetrics(getResources().getDisplayMetrics())
        .setNativeSpellCheckServiceDefined(isNativeSpellCheckServiceDefined)
        .setBrieflyShowPassword(
            Settings.System.getInt(
                    getContext().getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD, 1)
                == 1)
        .setUse24HourFormat(DateFormat.is24HourFormat(getContext()))
        .setPlatformBrightness(brightness)
        .send();
  }

  private FlutterViewDelegate delegate = new FlutterViewDelegate();

  @VisibleForTesting
  public void setDelegate(@NonNull FlutterViewDelegate delegate) {
    this.delegate = delegate;
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    widthMode = MeasureSpec.getMode(widthMeasureSpec);
    heightMode = MeasureSpec.getMode(heightMeasureSpec);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  }

  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;
    viewportMetrics.physicalTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
    flutterEngine.getRenderer().setViewportMetrics(viewportMetrics);
  }

  @Override
  public void onProvideAutofillVirtualStructure(@NonNull ViewStructure structure, int flags) {
    super.onProvideAutofillVirtualStructure(structure, flags);
    // Defensive null check to prevent NPE when textInputPlugin is not yet initialized
    // (e.g., when attachToEngineAutomatically is false).
    if (textInputPlugin != null) {
      textInputPlugin.onProvideAutofillVirtualStructure(structure, flags);
    }
  }

  @Override