Skip to content

Commit ce1b620

Browse files
stuartmorgan-gcfontas
authored andcommitted
Remove context assertion from Android platform views using Virtual Display (flutter#35997)
1 parent 0cada84 commit ce1b620

File tree

6 files changed

+87
-7
lines changed

6 files changed

+87
-7
lines changed

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
@Keep
5454
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
5555
class SingleViewPresentation extends Presentation {
56+
private static final String TAG = "PlatformViewsController";
5657

5758
/*
5859
* When an embedded view is resized in Flutterverse we move the Android view to a new virtual display
@@ -184,10 +185,20 @@ protected void onCreate(Bundle savedInstanceState) {
184185
MutableContextWrapper currentContext = (MutableContextWrapper) embeddedView.getContext();
185186
currentContext.setBaseContext(baseContext);
186187
} else {
187-
throw new IllegalStateException(
188-
"Unexpected platform view context. "
189-
+ "When constructing a platform view in the factory, use the context from PlatformViewFactory#create, view id: "
190-
+ viewId);
188+
// In some cases, such as when using LayoutInflator, the original context
189+
// may not be preserved. For backward compatibility with previous
190+
// implementations of Virtual Display, which didn't validate the context,
191+
// continue, but log a warning indicating that some functionality may not
192+
// work as expected.
193+
// See https://github.com/flutter/flutter/issues/110146 for context.
194+
Log.w(
195+
TAG,
196+
"Unexpected platform view context for view ID "
197+
+ viewId
198+
+ "; some functionality may not work correctly. When constructing a platform view "
199+
+ "in the factory, ensure that the view returned from PlatformViewFactory#create "
200+
+ "returns the provided context from getContext(). If you are unable to associate "
201+
+ "the view with that context, consider using Hybrid Composition instead.");
191202
}
192203

193204
container.addView(embeddedView);

testing/scenario_app/android/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ _android_sources = [
1313
"app/src/androidTest/java/dev/flutter/scenariosui/MemoryLeakTests.java",
1414
"app/src/androidTest/java/dev/flutter/scenariosui/PlatformTextureUiTests.java",
1515
"app/src/androidTest/java/dev/flutter/scenariosui/PlatformViewUiTests.java",
16+
"app/src/androidTest/java/dev/flutter/scenariosui/PlatformViewWithSurfaceViewBadContextUiTest.java",
1617
"app/src/androidTest/java/dev/flutter/scenariosui/PlatformViewWithSurfaceViewUiTest.java",
1718
"app/src/androidTest/java/dev/flutter/scenariosui/PlatformViewWithTextureViewUiTest.java",
1819
"app/src/androidTest/java/dev/flutter/scenariosui/ScreenshotUtil.java",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
package dev.flutter.scenariosui;
6+
7+
import android.content.Intent;
8+
import androidx.annotation.NonNull;
9+
import androidx.test.filters.LargeTest;
10+
import androidx.test.rule.ActivityTestRule;
11+
import androidx.test.runner.AndroidJUnit4;
12+
import dev.flutter.scenarios.PlatformViewsActivity;
13+
import org.junit.Before;
14+
import org.junit.Rule;
15+
import org.junit.Test;
16+
import org.junit.runner.RunWith;
17+
18+
@RunWith(AndroidJUnit4.class)
19+
@LargeTest
20+
public class PlatformViewWithSurfaceViewBadContextUiTest {
21+
Intent intent;
22+
23+
@Rule @NonNull
24+
public ActivityTestRule<PlatformViewsActivity> activityRule =
25+
new ActivityTestRule<>(
26+
PlatformViewsActivity.class, /*initialTouchMode=*/ false, /*launchActivity=*/ false);
27+
28+
private static String goldName(String suffix) {
29+
return "PlatformViewWithSurfaceViewBadContextUiTest_" + suffix;
30+
}
31+
32+
@Before
33+
public void setUp() {
34+
intent = new Intent(Intent.ACTION_MAIN);
35+
// Render a texture.
36+
intent.putExtra("use_android_view", false);
37+
intent.putExtra("view_type", PlatformViewsActivity.SURFACE_VIEW_BAD_CONTEXT_PV);
38+
}
39+
40+
@Test
41+
public void testPlatformView() throws Exception {
42+
intent.putExtra("scenario_name", "platform_view");
43+
ScreenshotUtil.capture(activityRule.launchActivity(intent), goldName("testPlatformView"));
44+
}
45+
}

testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/PlatformViewsActivity.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@
88
import io.flutter.embedding.engine.FlutterEngine;
99

1010
public class PlatformViewsActivity extends TestActivity {
11+
// WARNING: These strings must all be exactly the same length to avoid
12+
// breaking the 'create' method's manual encoding in the test. See the
13+
// TODO(stuartmorgan) about encoding alignment in platform_view.dart
1114
public static final String TEXT_VIEW_PV = "scenarios/textPlatformView";
1215
public static final String SURFACE_VIEW_PV = "scenarios/surfacePlatformV";
16+
public static final String SURFACE_VIEW_BAD_CONTEXT_PV = "scenarios/surfaceVBadCntxt";
1317
public static final String TEXTURE_VIEW_PV = "scenarios/texturePlatformV";
1418

1519
@Override
@@ -23,7 +27,12 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
2327
flutterEngine
2428
.getPlatformViewsController()
2529
.getRegistry()
26-
.registerViewFactory(SURFACE_VIEW_PV, new SurfacePlatformViewFactory());
30+
.registerViewFactory(SURFACE_VIEW_PV, new SurfacePlatformViewFactory(true));
31+
32+
flutterEngine
33+
.getPlatformViewsController()
34+
.getRegistry()
35+
.registerViewFactory(SURFACE_VIEW_BAD_CONTEXT_PV, new SurfacePlatformViewFactory(false));
2736

2837
flutterEngine
2938
.getPlatformViewsController()

testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/SurfacePlatformViewFactory.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import android.annotation.TargetApi;
88
import android.content.Context;
9+
import android.content.ContextWrapper;
910
import android.graphics.Canvas;
1011
import android.graphics.Color;
1112
import android.graphics.Paint;
@@ -24,7 +25,9 @@
2425

2526
@TargetApi(23)
2627
public final class SurfacePlatformViewFactory extends PlatformViewFactory {
27-
SurfacePlatformViewFactory() {
28+
private boolean preserveContext;
29+
30+
SurfacePlatformViewFactory(boolean preserveContext) {
2831
super(
2932
new MessageCodec<Object>() {
3033
@Nullable
@@ -42,13 +45,19 @@ public Object decodeMessage(@Nullable ByteBuffer byteBuffer) {
4245
return StringCodec.INSTANCE.decodeMessage(byteBuffer);
4346
}
4447
});
48+
this.preserveContext = preserveContext;
4549
}
4650

4751
@SuppressWarnings("unchecked")
4852
@Override
4953
@NonNull
5054
public PlatformView create(@NonNull Context context, int id, @Nullable Object args) {
51-
return new SurfacePlatformView(context);
55+
if (preserveContext) {
56+
return new SurfacePlatformView(context);
57+
} else {
58+
final Context differentContext = new ContextWrapper(context);
59+
return new SurfacePlatformView(differentContext);
60+
}
5261
}
5362

5463
private static class SurfacePlatformView implements PlatformView {

testing/scenario_app/lib/src/platform_view.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,11 @@ void addPlatformView(
11441144
valueString,
11451145
'width'.length,
11461146
...utf8.encode('width'),
1147+
// This is missing the 64-bit boundary alignment, making the entire
1148+
// message encoding fragile to changes before this point. Do not add new
1149+
// variable-length values such as strings before this point.
1150+
// TODO(stuartmorgan): Fix this to use the actual encoding logic,
1151+
// including alignment: https://github.com/flutter/flutter/issues/111188
11471152
valueFloat64,
11481153
..._to64(width),
11491154
valueString,

0 commit comments

Comments
 (0)