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

Commit 7b9ac27

Browse files
authored
Revert "Create PlatformView instance right after method channel call from Dart (#20500)" (#20564)
This reverts commit 9333b7c.
1 parent 41971f4 commit 7b9ac27

File tree

2 files changed

+65
-100
lines changed

2 files changed

+65
-100
lines changed

shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega
7979
// it is associated with(e.g if a platform view creates other views in the same virtual display.
8080
private final HashMap<Context, View> contextToPlatformView;
8181

82+
private final SparseArray<PlatformViewsChannel.PlatformViewCreationRequest> platformViewRequests;
8283
private final SparseArray<View> platformViews;
8384
private final SparseArray<FlutterMutatorView> mutatorViews;
8485

@@ -106,45 +107,18 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega
106107
@Override
107108
public void createAndroidViewForPlatformView(
108109
@NonNull PlatformViewsChannel.PlatformViewCreationRequest request) {
109-
// API level 19 is required for `android.graphics.ImageReader`.
110+
// API level 19 is required for android.graphics.ImageReader.
110111
ensureValidAndroidVersion(Build.VERSION_CODES.KITKAT);
111-
112-
if (!validateDirection(request.direction)) {
113-
throw new IllegalStateException(
114-
"Trying to create a view with unknown direction value: "
115-
+ request.direction
116-
+ "(view id: "
117-
+ request.viewId
118-
+ ")");
119-
}
120-
121-
final PlatformViewFactory factory = registry.getFactory(request.viewType);
122-
if (factory == null) {
123-
throw new IllegalStateException(
124-
"Trying to create a platform view of unregistered type: " + request.viewType);
125-
}
126-
127-
Object createParams = null;
128-
if (request.params != null) {
129-
createParams = factory.getCreateArgsCodec().decodeMessage(request.params);
130-
}
131-
132-
final PlatformView platformView = factory.create(context, request.viewId, createParams);
133-
final View view = platformView.getView();
134-
if (view == null) {
135-
throw new IllegalStateException(
136-
"PlatformView#getView() returned null, but an Android view reference was expected.");
137-
}
138-
if (view.getParent() != null) {
139-
throw new IllegalStateException(
140-
"The Android view returned from PlatformView#getView() was already added to a parent view.");
141-
}
142-
platformViews.put(request.viewId, view);
112+
platformViewRequests.put(request.viewId, request);
143113
}
144114

145115
@Override
146116
public void disposeAndroidViewForPlatformView(int viewId) {
147117
// Hybrid view.
118+
if (platformViewRequests.get(viewId) != null) {
119+
platformViewRequests.remove(viewId);
120+
}
121+
148122
final View platformView = platformViews.get(viewId);
149123
if (platformView != null) {
150124
final FlutterMutatorView mutatorView = mutatorViews.get(viewId);
@@ -404,6 +378,7 @@ public PlatformViewsController() {
404378
currentFrameUsedOverlayLayerIds = new HashSet<>();
405379
currentFrameUsedPlatformViewIds = new HashSet<>();
406380

381+
platformViewRequests = new SparseArray<>();
407382
platformViews = new SparseArray<>();
408383
mutatorViews = new SparseArray<>();
409384

@@ -676,15 +651,50 @@ private void initializeRootImageViewIfNeeded() {
676651

677652
@VisibleForTesting
678653
void initializePlatformViewIfNeeded(int viewId) {
679-
final View view = platformViews.get(viewId);
680-
if (view == null) {
654+
if (platformViews.get(viewId) != null) {
655+
return;
656+
}
657+
658+
PlatformViewsChannel.PlatformViewCreationRequest request = platformViewRequests.get(viewId);
659+
if (request == null) {
681660
throw new IllegalStateException(
682661
"Platform view hasn't been initialized from the platform view channel.");
683662
}
684-
if (mutatorViews.get(viewId) != null) {
685-
return;
663+
664+
if (!validateDirection(request.direction)) {
665+
throw new IllegalStateException(
666+
"Trying to create a view with unknown direction value: "
667+
+ request.direction
668+
+ "(view id: "
669+
+ viewId
670+
+ ")");
671+
}
672+
673+
PlatformViewFactory factory = registry.getFactory(request.viewType);
674+
if (factory == null) {
675+
throw new IllegalStateException(
676+
"Trying to create a platform view of unregistered type: " + request.viewType);
677+
}
678+
679+
Object createParams = null;
680+
if (request.params != null) {
681+
createParams = factory.getCreateArgsCodec().decodeMessage(request.params);
686682
}
687-
final FlutterMutatorView mutatorView =
683+
684+
PlatformView platformView = factory.create(context, viewId, createParams);
685+
View view = platformView.getView();
686+
687+
if (view == null) {
688+
throw new IllegalStateException(
689+
"PlatformView#getView() returned null, but an Android view reference was expected.");
690+
}
691+
if (view.getParent() != null) {
692+
throw new IllegalStateException(
693+
"The Android view returned from PlatformView#getView() was already added to a parent view.");
694+
}
695+
platformViews.put(viewId, view);
696+
697+
FlutterMutatorView mutatorView =
688698
new FlutterMutatorView(
689699
context, context.getResources().getDisplayMetrics().density, androidTouchProcessor);
690700
mutatorViews.put(viewId, mutatorView);

shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java

Lines changed: 17 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import android.content.Context;
99
import android.content.res.AssetManager;
10-
import android.util.SparseArray;
1110
import android.view.MotionEvent;
1211
import android.view.Surface;
1312
import android.view.SurfaceHolder;
@@ -29,9 +28,7 @@
2928
import io.flutter.embedding.engine.systemchannels.MouseCursorChannel;
3029
import io.flutter.embedding.engine.systemchannels.SettingsChannel;
3130
import io.flutter.embedding.engine.systemchannels.TextInputChannel;
32-
import io.flutter.plugin.common.FlutterException;
3331
import io.flutter.plugin.common.MethodCall;
34-
import io.flutter.plugin.common.StandardMessageCodec;
3532
import io.flutter.plugin.common.StandardMethodCodec;
3633
import io.flutter.plugin.localization.LocalizationPlugin;
3734
import java.nio.ByteBuffer;
@@ -245,29 +242,7 @@ public void getPlatformViewById__hybridComposition() {
245242

246243
@Test
247244
@Config(shadows = {ShadowFlutterJNI.class})
248-
public void createPlatformViewMessage__initializesAndroidView() {
249-
PlatformViewsController platformViewsController = new PlatformViewsController();
250-
251-
int platformViewId = 0;
252-
assertNull(platformViewsController.getPlatformViewById(platformViewId));
253-
254-
PlatformViewFactory viewFactory = mock(PlatformViewFactory.class);
255-
PlatformView platformView = mock(PlatformView.class);
256-
when(platformView.getView()).thenReturn(mock(View.class));
257-
when(viewFactory.create(any(), eq(platformViewId), any())).thenReturn(platformView);
258-
platformViewsController.getRegistry().registerViewFactory("testType", viewFactory);
259-
260-
FlutterJNI jni = new FlutterJNI();
261-
attach(jni, platformViewsController);
262-
263-
// Simulate create call from the framework.
264-
createPlatformView(jni, platformViewsController, platformViewId, "testType");
265-
verify(platformView, times(1)).getView();
266-
}
267-
268-
@Test
269-
@Config(shadows = {ShadowFlutterJNI.class})
270-
public void createPlatformViewMessage__throwsIfViewIsNull() {
245+
public void initializePlatformViewIfNeeded__throwsIfViewIsNull() {
271246
PlatformViewsController platformViewsController = new PlatformViewsController();
272247

273248
int platformViewId = 0;
@@ -284,28 +259,22 @@ public void createPlatformViewMessage__throwsIfViewIsNull() {
284259

285260
// Simulate create call from the framework.
286261
createPlatformView(jni, platformViewsController, platformViewId, "testType");
287-
assertEquals(ShadowFlutterJNI.getResponses().size(), 1);
288262

289-
final ByteBuffer responseBuffer = ShadowFlutterJNI.getResponses().get(0);
290-
responseBuffer.rewind();
291-
292-
StandardMethodCodec methodCodec = new StandardMethodCodec(new StandardMessageCodec());
293263
try {
294-
methodCodec.decodeEnvelope(responseBuffer);
295-
} catch (FlutterException exception) {
296-
assertTrue(
297-
exception
298-
.getMessage()
299-
.contains(
300-
"PlatformView#getView() returned null, but an Android view reference was expected."));
264+
platformViewsController.initializePlatformViewIfNeeded(platformViewId);
265+
} catch (Exception exception) {
266+
assertTrue(exception instanceof IllegalStateException);
267+
assertEquals(
268+
exception.getMessage(),
269+
"PlatformView#getView() returned null, but an Android view reference was expected.");
301270
return;
302271
}
303-
assertFalse(true);
272+
assertTrue(false);
304273
}
305274

306275
@Test
307276
@Config(shadows = {ShadowFlutterJNI.class})
308-
public void createPlatformViewMessage__throwsIfViewHasParent() {
277+
public void initializePlatformViewIfNeeded__throwsIfViewHasParent() {
309278
PlatformViewsController platformViewsController = new PlatformViewsController();
310279

311280
int platformViewId = 0;
@@ -324,23 +293,16 @@ public void createPlatformViewMessage__throwsIfViewHasParent() {
324293

325294
// Simulate create call from the framework.
326295
createPlatformView(jni, platformViewsController, platformViewId, "testType");
327-
assertEquals(ShadowFlutterJNI.getResponses().size(), 1);
328-
329-
final ByteBuffer responseBuffer = ShadowFlutterJNI.getResponses().get(0);
330-
responseBuffer.rewind();
331-
332-
StandardMethodCodec methodCodec = new StandardMethodCodec(new StandardMessageCodec());
333296
try {
334-
methodCodec.decodeEnvelope(responseBuffer);
335-
} catch (FlutterException exception) {
336-
assertTrue(
337-
exception
338-
.getMessage()
339-
.contains(
340-
"The Android view returned from PlatformView#getView() was already added to a parent view."));
297+
platformViewsController.initializePlatformViewIfNeeded(platformViewId);
298+
} catch (Exception exception) {
299+
assertTrue(exception instanceof IllegalStateException);
300+
assertEquals(
301+
exception.getMessage(),
302+
"The Android view returned from PlatformView#getView() was already added to a parent view.");
341303
return;
342304
}
343-
assertFalse(true);
305+
assertTrue(false);
344306
}
345307

346308
@Test
@@ -519,7 +481,6 @@ public FlutterImageView createImageView() {
519481

520482
@Implements(FlutterJNI.class)
521483
public static class ShadowFlutterJNI {
522-
private static SparseArray<ByteBuffer> replies = new SparseArray<>();
523484

524485
public ShadowFlutterJNI() {}
525486

@@ -566,13 +527,7 @@ public void setViewportMetrics(
566527

567528
@Implementation
568529
public void invokePlatformMessageResponseCallback(
569-
int responseId, ByteBuffer message, int position) {
570-
replies.put(responseId, message);
571-
}
572-
573-
public static SparseArray<ByteBuffer> getResponses() {
574-
return replies;
575-
}
530+
int responseId, ByteBuffer message, int position) {}
576531
}
577532

578533
@Implements(SurfaceView.class)

0 commit comments

Comments
 (0)