Clone the parent Android engine's asset provider into a spawned engine (flutter/engine#41642)
Typically the AndroidShellHolder's apk_asset_provider_ is set by AndroidShellHolder::Launch when the DartExecutor runs the engine's entrypoint. But if the engine was started by Spawn, then the apk_asset_provider_ was not being set. This would cause a crash if the resulting engine was later used to spawn another engine. Fixes https://github.com/flutter/flutter/issues/122364
This commit is contained in:
@@ -180,12 +180,14 @@ AndroidShellHolder::AndroidShellHolder(
|
||||
const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
|
||||
const std::shared_ptr<ThreadHost>& thread_host,
|
||||
std::unique_ptr<Shell> shell,
|
||||
std::unique_ptr<APKAssetProvider> apk_asset_provider,
|
||||
const fml::WeakPtr<PlatformViewAndroid>& platform_view)
|
||||
: settings_(settings),
|
||||
jni_facade_(jni_facade),
|
||||
platform_view_(platform_view),
|
||||
thread_host_(thread_host),
|
||||
shell_(std::move(shell)) {
|
||||
shell_(std::move(shell)),
|
||||
apk_asset_provider_(std::move(apk_asset_provider)) {
|
||||
FML_DCHECK(jni_facade);
|
||||
FML_DCHECK(shell_);
|
||||
FML_DCHECK(shell_->IsSetup());
|
||||
@@ -270,9 +272,9 @@ std::unique_ptr<AndroidShellHolder> AndroidShellHolder::Spawn(
|
||||
shell_->Spawn(std::move(config.value()), initial_route,
|
||||
on_create_platform_view, on_create_rasterizer);
|
||||
|
||||
return std::unique_ptr<AndroidShellHolder>(
|
||||
new AndroidShellHolder(GetSettings(), jni_facade, thread_host_,
|
||||
std::move(shell), weak_platform_view));
|
||||
return std::unique_ptr<AndroidShellHolder>(new AndroidShellHolder(
|
||||
GetSettings(), jni_facade, thread_host_, std::move(shell),
|
||||
apk_asset_provider_->Clone(), weak_platform_view));
|
||||
}
|
||||
|
||||
void AndroidShellHolder::Launch(
|
||||
|
||||
@@ -128,6 +128,7 @@ class AndroidShellHolder {
|
||||
const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
|
||||
const std::shared_ptr<ThreadHost>& thread_host,
|
||||
std::unique_ptr<Shell> shell,
|
||||
std::unique_ptr<APKAssetProvider> apk_asset_provider,
|
||||
const fml::WeakPtr<PlatformViewAndroid>& platform_view);
|
||||
static void ThreadDestructCallback(void* value);
|
||||
std::optional<RunConfiguration> BuildRunConfiguration(
|
||||
|
||||
@@ -21,9 +21,11 @@ _android_sources = [
|
||||
"app/src/androidTest/java/dev/flutter/scenariosui/PlatformViewWithTextureViewUiTest.java",
|
||||
"app/src/androidTest/java/dev/flutter/scenariosui/ScreenshotUtil.java",
|
||||
"app/src/androidTest/java/dev/flutter/scenariosui/SpawnEngineTests.java",
|
||||
"app/src/androidTest/java/dev/flutter/scenariosui/SpawnMultiEngineTest.java",
|
||||
"app/src/main/AndroidManifest.xml",
|
||||
"app/src/main/java/dev/flutter/scenarios/GetBitmapActivity.java",
|
||||
"app/src/main/java/dev/flutter/scenarios/PlatformViewsActivity.java",
|
||||
"app/src/main/java/dev/flutter/scenarios/SpawnMultiEngineActivity.java",
|
||||
"app/src/main/java/dev/flutter/scenarios/SpawnedEngineActivity.java",
|
||||
"app/src/main/java/dev/flutter/scenarios/StrictModeFlutterActivity.java",
|
||||
"app/src/main/java/dev/flutter/scenarios/SurfacePlatformViewFactory.java",
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// 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 dev.flutter.scenariosui;
|
||||
|
||||
import android.content.Intent;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
import dev.flutter.scenarios.SpawnMultiEngineActivity;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@LargeTest
|
||||
public class SpawnMultiEngineTest {
|
||||
Intent intent;
|
||||
|
||||
@Rule @NonNull
|
||||
public ActivityTestRule<SpawnMultiEngineActivity> activityRule =
|
||||
new ActivityTestRule<>(
|
||||
SpawnMultiEngineActivity.class, /*initialTouchMode=*/ false, /*launchActivity=*/ false);
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
intent = new Intent(Intent.ACTION_MAIN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpawnedEngine() throws Exception {
|
||||
activityRule.launchActivity(intent);
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,18 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".SpawnMultiEngineActivity"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:launchMode="singleTop"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ExternalTextureFlutterActivity"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// 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 dev.flutter.scenarios;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import io.flutter.embedding.engine.FlutterEngine;
|
||||
import io.flutter.embedding.engine.FlutterEngineGroup;
|
||||
|
||||
public class SpawnMultiEngineActivity extends TestActivity {
|
||||
static final String TAG = "Scenarios";
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public FlutterEngine provideFlutterEngine(@NonNull Context context) {
|
||||
FlutterEngineGroup engineGroup = new FlutterEngineGroup(context);
|
||||
FlutterEngine firstEngine = engineGroup.createAndRunDefaultEngine(context);
|
||||
|
||||
FlutterEngine secondEngine = engineGroup.createAndRunDefaultEngine(context);
|
||||
|
||||
// Check that a new engine can be spawned from the group even if the group's
|
||||
// original engine has been destroyed.
|
||||
firstEngine.destroy();
|
||||
FlutterEngine thirdEngine = engineGroup.createAndRunDefaultEngine(context);
|
||||
|
||||
return thirdEngine;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user