Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Revert "Improve platform views performance" #31431

Merged
merged 1 commit into from
Feb 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1189,9 +1189,10 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/Platfor
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewFactory.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewRegistry.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewRegistryImpl.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewWrapper.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsAccessibilityDelegate.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/SingleViewPresentation.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java
FILE: ../../../flutter/shell/platform/android/io/flutter/util/PathUtils.java
FILE: ../../../flutter/shell/platform/android/io/flutter/util/Preconditions.java
FILE: ../../../flutter/shell/platform/android/io/flutter/util/Predicate.java
Expand Down
3 changes: 2 additions & 1 deletion shell/platform/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,10 @@ android_java_sources = [
"io/flutter/plugin/platform/PlatformViewFactory.java",
"io/flutter/plugin/platform/PlatformViewRegistry.java",
"io/flutter/plugin/platform/PlatformViewRegistryImpl.java",
"io/flutter/plugin/platform/PlatformViewWrapper.java",
"io/flutter/plugin/platform/PlatformViewsAccessibilityDelegate.java",
"io/flutter/plugin/platform/PlatformViewsController.java",
"io/flutter/plugin/platform/SingleViewPresentation.java",
"io/flutter/plugin/platform/VirtualDisplayController.java",
"io/flutter/util/PathUtils.java",
"io/flutter/util/Preconditions.java",
"io/flutter/util/Predicate.java",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public boolean onTouchEvent(@NonNull MotionEvent event) {
* the gesture pointers into screen coordinates.
* @return True if the event was handled.
*/
public boolean onTouchEvent(@NonNull MotionEvent event, @NonNull Matrix transformMatrix) {
public boolean onTouchEvent(@NonNull MotionEvent event, Matrix transformMatrix) {
int pointerCount = event.getPointerCount();

// Prepare a data packet of the appropriate size and order.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,7 @@ navigationBarVisible && guessBottomKeyboardInset(insets) == 0
+ viewportMetrics.viewInsetBottom);

sendViewportMetricsToFlutter();

return newInsets;
}

Expand Down Expand Up @@ -866,6 +867,21 @@ public InputConnection onCreateInputConnection(@NonNull EditorInfo outAttrs) {
return textInputPlugin.createInputConnection(this, keyboardManager, 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 a hardware key is pressed or released.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
import android.graphics.Path;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import io.flutter.embedding.android.AndroidTouchProcessor;
import io.flutter.util.ViewUtils;

/**
* A view that applies the {@link io.flutter.embedding.engine.mutatorsstack.FlutterMutatorsStack} to
Expand Down Expand Up @@ -49,6 +49,31 @@ public FlutterMutatorView(@NonNull Context context) {
this(context, 1, /* androidTouchProcessor=*/ null);
}

/**
* Determines if the current view or any descendant view has focus.
*
* @param root The root view.
* @return True if the current view or any descendant view has focus.
*/
@VisibleForTesting
public static boolean childHasFocus(@Nullable View root) {
if (root == null) {
return false;
}
if (root.hasFocus()) {
return true;
}
if (root instanceof ViewGroup) {
final ViewGroup viewGroup = (ViewGroup) root;
for (int idx = 0; idx < viewGroup.getChildCount(); idx++) {
if (childHasFocus(viewGroup.getChildAt(idx))) {
return true;
}
}
}
return false;
}

@Nullable @VisibleForTesting ViewTreeObserver.OnGlobalFocusChangeListener activeFocusListener;

/**
Expand All @@ -70,7 +95,7 @@ public void setOnDescendantFocusChangeListener(@NonNull OnFocusChangeListener us
new ViewTreeObserver.OnGlobalFocusChangeListener() {
@Override
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
userFocusListener.onFocusChange(mutatorView, ViewUtils.childHasFocus(mutatorView));
userFocusListener.onFocusChange(mutatorView, childHasFocus(mutatorView));
}
};
observer.addOnGlobalFocusChangeListener(activeFocusListener);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -65,9 +64,6 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
case "resize":
resize(call, result);
break;
case "offset":
offset(call, result);
break;
case "touch":
touch(call, result);
break;
Expand All @@ -86,40 +82,29 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
}

private void create(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
final Map<String, Object> createArgs = call.arguments();
// TODO(egarciad): Remove the "hybrid" case.
final boolean usesPlatformViewLayer =
Map<String, Object> createArgs = call.arguments();
boolean usesHybridComposition =
createArgs.containsKey("hybrid") && (boolean) createArgs.get("hybrid");
final ByteBuffer additionalParams =
createArgs.containsKey("params")
? ByteBuffer.wrap((byte[]) createArgs.get("params"))
: null;
// In hybrid mode, the size of the view is determined by the size of the Flow layer.
double width = (usesHybridComposition) ? 0 : (double) createArgs.get("width");
double height = (usesHybridComposition) ? 0 : (double) createArgs.get("height");

PlatformViewCreationRequest request =
new PlatformViewCreationRequest(
(int) createArgs.get("id"),
(String) createArgs.get("viewType"),
width,
height,
(int) createArgs.get("direction"),
createArgs.containsKey("params")
? ByteBuffer.wrap((byte[]) createArgs.get("params"))
: null);
try {
if (usesPlatformViewLayer) {
final PlatformViewCreationRequest request =
new PlatformViewCreationRequest(
(int) createArgs.get("id"),
(String) createArgs.get("viewType"),
0,
0,
0,
0,
(int) createArgs.get("direction"),
additionalParams);
handler.createForPlatformViewLayer(request);
if (usesHybridComposition) {
handler.createAndroidViewForPlatformView(request);
result.success(null);
} else {
final PlatformViewCreationRequest request =
new PlatformViewCreationRequest(
(int) createArgs.get("id"),
(String) createArgs.get("viewType"),
createArgs.containsKey("top") ? (double) createArgs.get("top") : 0.0,
createArgs.containsKey("left") ? (double) createArgs.get("left") : 0.0,
(double) createArgs.get("width"),
(double) createArgs.get("height"),
(int) createArgs.get("direction"),
additionalParams);
long textureId = handler.createForTextureLayer(request);
long textureId = handler.createVirtualDisplayForPlatformView(request);
result.success(textureId);
}
} catch (IllegalStateException exception) {
Expand All @@ -130,9 +115,15 @@ private void create(@NonNull MethodCall call, @NonNull MethodChannel.Result resu
private void dispose(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
Map<String, Object> disposeArgs = call.arguments();
int viewId = (int) disposeArgs.get("id");
boolean usesHybridComposition =
disposeArgs.containsKey("hybrid") && (boolean) disposeArgs.get("hybrid");

try {
handler.dispose(viewId);
if (usesHybridComposition) {
handler.disposeAndroidViewForPlatformView(viewId);
} else {
handler.disposeVirtualDisplayForPlatformView(viewId);
}
result.success(null);
} catch (IllegalStateException exception) {
result.error("error", detailedExceptionString(exception), null);
Expand All @@ -147,28 +138,14 @@ private void resize(@NonNull MethodCall call, @NonNull MethodChannel.Result resu
(double) resizeArgs.get("width"),
(double) resizeArgs.get("height"));
try {
final PlatformViewBufferSize sz = handler.resize(resizeRequest);
if (sz == null) {
result.error("error", "Failed to resize the platform view", null);
} else {
final Map<String, Object> response = new HashMap<>();
response.put("width", (double) sz.width);
response.put("height", (double) sz.height);
result.success(response);
}
} catch (IllegalStateException exception) {
result.error("error", detailedExceptionString(exception), null);
}
}

private void offset(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
Map<String, Object> offsetArgs = call.arguments();
try {
handler.offset(
(int) offsetArgs.get("id"),
(double) offsetArgs.get("top"),
(double) offsetArgs.get("left"));
result.success(null);
handler.resizePlatformView(
resizeRequest,
new Runnable() {
@Override
public void run() {
result.success(null);
}
});
} catch (IllegalStateException exception) {
result.error("error", detailedExceptionString(exception), null);
}
Expand Down Expand Up @@ -272,40 +249,36 @@ public interface PlatformViewsHandler {
* The Flutter application would like to display a new Android {@code View}, i.e., platform
* view.
*
* <p>The Android View is added to the view hierarchy. This view is rendered in the Flutter
* framework by a PlatformViewLayer.
*
* @param request The metadata sent from the framework.
* <p>The Android {@code View} is added to the view hierarchy.
*/
void createForPlatformViewLayer(@NonNull PlatformViewCreationRequest request);
void createAndroidViewForPlatformView(@NonNull PlatformViewCreationRequest request);

/**
* The Flutter application would like to display a new Android {@code View}, i.e., platform
* view.
*
* <p>The Android View is added to the view hierarchy. This view is rendered in the Flutter
* framework by a TextureLayer.
*
* @param request The metadata sent from the framework.
* @return The texture ID.
* The Flutter application would like to dispose of an existing Android {@code View} rendered in
* the view hierarchy.
*/
long createForTextureLayer(@NonNull PlatformViewCreationRequest request);

/** The Flutter application would like to dispose of an existing Android {@code View}. */
void dispose(int viewId);
void disposeAndroidViewForPlatformView(int viewId);

/**
* The Flutter application would like to resize an existing Android {@code View}.
* The Flutter application would like to display a new Android {@code View}.
*
* @param request The request to resize the platform view.
* @return The buffer size where the platform view pixels are written to.
* <p>{@code View} is added to a {@code VirtualDisplay}. The framework uses id returned by this
* method to lookup the texture in the engine.
*/
long createVirtualDisplayForPlatformView(@NonNull PlatformViewCreationRequest request);

/**
* The Flutter application would like to dispose of an existing Android {@code View} rendered in
* a virtual display.
*/
PlatformViewBufferSize resize(@NonNull PlatformViewResizeRequest request);
void disposeVirtualDisplayForPlatformView(int viewId);

/**
* The Flutter application would like to change the offset of an existing Android {@code View}.
* The Flutter application would like to resize an existing Android {@code View}, i.e., platform
* view.
*/
void offset(int viewId, double top, double left);
void resizePlatformView(
@NonNull PlatformViewResizeRequest request, @NonNull Runnable onComplete);

/**
* The user touched a platform view within Flutter.
Expand Down Expand Up @@ -348,12 +321,6 @@ public static class PlatformViewCreationRequest {
/** The density independent height to display the platform view. */
public final double logicalHeight;

/** The density independent top position to display the platform view. */
public final double logicalTop;

/** The density independent left position to display the platform view. */
public final double logicalLeft;

/**
* The layout direction of the new platform view.
*
Expand All @@ -365,28 +332,28 @@ public static class PlatformViewCreationRequest {
/** Custom parameters that are unique to the desired platform view. */
@Nullable public final ByteBuffer params;

/** Creates a request to construct a platform view. */
/** Creates a request to construct a platform view that uses a virtual display. */
public PlatformViewCreationRequest(
int viewId,
@NonNull String viewType,
double logicalTop,
double logicalLeft,
double logicalWidth,
double logicalHeight,
int direction,
@Nullable ByteBuffer params) {
this.viewId = viewId;
this.viewType = viewType;
this.logicalTop = logicalTop;
this.logicalLeft = logicalLeft;
this.logicalWidth = logicalWidth;
this.logicalHeight = logicalHeight;
this.direction = direction;
this.params = params;
}
}

/** Request sent from Flutter to resize a platform view. */
/**
* Request sent from Flutter to resize a platform view.
*
* <p>This only applies to platform views that use virtual displays.
*/
public static class PlatformViewResizeRequest {
/** The ID of the platform view as seen by the Flutter side. */
public final int viewId;
Expand All @@ -404,20 +371,6 @@ public PlatformViewResizeRequest(int viewId, double newLogicalWidth, double newL
}
}

/** The platform view buffer size. */
public static class PlatformViewBufferSize {
/** The width of the screen buffer. */
public final int width;

/** The height of the screen buffer. */
public final int height;

public PlatformViewBufferSize(int width, int height) {
this.width = width;
this.height = height;
}
}

/** The state of a touch event in Flutter within a platform view. */
public static class PlatformViewTouch {
/** The ID of the platform view as seen by the Flutter side. */
Expand Down
Loading