AssetResolver updating in AssetManager for Dynamic features (flutter/engine#23130)

This commit is contained in:
Gary Qian 2020-12-23 18:39:55 -07:00 committed by GitHub
parent 0bc19d5759
commit 2bfbb4197c
22 changed files with 382 additions and 51 deletions

View File

@ -29,6 +29,30 @@ void AssetManager::PushBack(std::unique_ptr<AssetResolver> resolver) {
resolvers_.push_back(std::move(resolver));
}
void AssetManager::UpdateResolverByType(
std::unique_ptr<AssetResolver> updated_asset_resolver,
AssetResolver::AssetResolverType type) {
if (updated_asset_resolver == nullptr) {
return;
}
bool updated = false;
std::deque<std::unique_ptr<AssetResolver>> new_resolvers;
for (auto& old_resolver : resolvers_) {
if (!updated && old_resolver->GetType() == type) {
// Push the replacement updated resolver in place of the old_resolver.
new_resolvers.push_back(std::move(updated_asset_resolver));
updated = true;
} else {
new_resolvers.push_back(std::move(old_resolver));
}
}
// Append resolver to the end if not used as a replacement.
if (!updated) {
new_resolvers.push_back(std::move(updated_asset_resolver));
}
resolvers_.swap(new_resolvers);
}
std::deque<std::unique_ptr<AssetResolver>> AssetManager::TakeResolvers() {
return std::move(resolvers_);
}
@ -79,4 +103,9 @@ bool AssetManager::IsValidAfterAssetManagerChange() const {
return false;
}
// |AssetResolver|
AssetResolver::AssetResolverType AssetManager::GetType() const {
return AssetResolverType::kAssetManager;
}
} // namespace flutter

View File

@ -25,6 +25,34 @@ class AssetManager final : public AssetResolver {
void PushBack(std::unique_ptr<AssetResolver> resolver);
//--------------------------------------------------------------------------
/// @brief Replaces an asset resolver of the specified `type` with
/// `updated_asset_resolver`. The matching AssetResolver is
/// removed and replaced with `updated_asset_resolvers`.
///
/// AssetResolvers should be updated when the existing resolver
/// becomes obsolete and a newer one becomes available that
/// provides updated access to the same type of assets as the
/// existing one. This update process is meant to be performed
/// at runtime.
///
/// If a null resolver is provided, nothing will be done. If no
/// matching resolver is found, the provided resolver will be
/// added to the end of the AssetManager resolvers queue. The
/// replacement only occurs with the first matching resolver.
/// Any additional matching resolvers are untouched.
///
/// @param[in] updated_asset_resolver The asset resolver to replace the
/// resolver of matching type with.
///
/// @param[in] type The type of AssetResolver to update. Only resolvers of
/// the specified type will be replaced by the updated
/// resolver.
///
void UpdateResolverByType(
std::unique_ptr<AssetResolver> updated_asset_resolver,
AssetResolver::AssetResolverType type);
std::deque<std::unique_ptr<AssetResolver>> TakeResolvers();
// |AssetResolver|
@ -33,6 +61,9 @@ class AssetManager final : public AssetResolver {
// |AssetResolver|
bool IsValidAfterAssetManagerChange() const override;
// |AssetResolver|
AssetResolver::AssetResolverType GetType() const override;
// |AssetResolver|
std::unique_ptr<fml::Mapping> GetAsMapping(
const std::string& asset_name) const override;

View File

@ -19,6 +19,15 @@ class AssetResolver {
virtual ~AssetResolver() = default;
//----------------------------------------------------------------------------
/// @brief Identifies the type of AssetResolver an instance is.
///
enum AssetResolverType {
kAssetManager,
kApkAssetProvider,
kDirectoryAssetBundle
};
virtual bool IsValid() const = 0;
//----------------------------------------------------------------------------
@ -39,6 +48,14 @@ class AssetResolver {
///
virtual bool IsValidAfterAssetManagerChange() const = 0;
//----------------------------------------------------------------------------
/// @brief Gets the type of AssetResolver this is. Types are defined in
/// AssetResolverType.
///
/// @return Returns the AssetResolverType that this resolver is.
///
virtual AssetResolverType GetType() const = 0;
[[nodiscard]] virtual std::unique_ptr<fml::Mapping> GetAsMapping(
const std::string& asset_name) const = 0;

View File

@ -36,6 +36,11 @@ bool DirectoryAssetBundle::IsValidAfterAssetManagerChange() const {
return is_valid_after_asset_manager_change_;
}
// |AssetResolver|
AssetResolver::AssetResolverType DirectoryAssetBundle::GetType() const {
return AssetResolver::AssetResolverType::kDirectoryAssetBundle;
}
// |AssetResolver|
std::unique_ptr<fml::Mapping> DirectoryAssetBundle::GetAsMapping(
const std::string& asset_name) const {

View File

@ -30,6 +30,9 @@ class DirectoryAssetBundle : public AssetResolver {
// |AssetResolver|
bool IsValidAfterAssetManagerChange() const override;
// |AssetResolver|
AssetResolver::AssetResolverType GetType() const override;
// |AssetResolver|
std::unique_ptr<fml::Mapping> GetAsMapping(
const std::string& asset_name) const override;

View File

@ -170,7 +170,10 @@ void PlatformView::LoadDartDeferredLibraryError(intptr_t loading_unit_id,
const std::string error_message,
bool transient) {}
void PlatformView::UpdateAssetManager(
std::shared_ptr<AssetManager> asset_manager) {}
void PlatformView::UpdateAssetResolverByType(
std::unique_ptr<AssetResolver> updated_asset_resolver,
AssetResolver::AssetResolverType type) {
delegate_.UpdateAssetResolverByType(std::move(updated_asset_resolver), type);
}
} // namespace flutter

View File

@ -273,15 +273,34 @@ class PlatformView {
const std::string error_message,
bool transient) = 0;
// TODO(garyq): Implement a proper asset_resolver replacement instead of
// overwriting the entire asset manager.
//--------------------------------------------------------------------------
/// @brief Sets the asset manager of the engine to asset_manager
/// @brief Replaces the asset resolver handled by the engine's
/// AssetManager of the specified `type` with
/// `updated_asset_resolver`. The matching AssetResolver is
/// removed and replaced with `updated_asset_resolvers`.
///
/// @param[in] asset_manager The asset manager to use.
/// AssetResolvers should be updated when the existing resolver
/// becomes obsolete and a newer one becomes available that
/// provides updated access to the same type of assets as the
/// existing one. This update process is meant to be performed
/// at runtime.
///
virtual void UpdateAssetManager(
std::shared_ptr<AssetManager> asset_manager) = 0;
/// If a null resolver is provided, nothing will be done. If no
/// matching resolver is found, the provided resolver will be
/// added to the end of the AssetManager resolvers queue. The
/// replacement only occurs with the first matching resolver.
/// Any additional matching resolvers are untouched.
///
/// @param[in] updated_asset_resolver The asset resolver to replace the
/// resolver of matching type with.
///
/// @param[in] type The type of AssetResolver to update. Only resolvers of
/// the specified type will be replaced by the updated
/// resolver.
///
virtual void UpdateAssetResolverByType(
std::unique_ptr<AssetResolver> updated_asset_resolver,
AssetResolver::AssetResolverType type) = 0;
};
//----------------------------------------------------------------------------
@ -720,14 +739,34 @@ class PlatformView {
const std::string error_message,
bool transient);
// TODO(garyq): Implement a proper asset_resolver replacement instead of
// overwriting the entire asset manager.
//--------------------------------------------------------------------------
/// @brief Sets the asset manager of the engine to asset_manager
/// @brief Replaces the asset resolver handled by the engine's
/// AssetManager of the specified `type` with
/// `updated_asset_resolver`. The matching AssetResolver is
/// removed and replaced with `updated_asset_resolvers`.
///
/// @param[in] asset_manager The asset manager to use.
/// AssetResolvers should be updated when the existing resolver
/// becomes obsolete and a newer one becomes available that
/// provides updated access to the same type of assets as the
/// existing one. This update process is meant to be performed
/// at runtime.
///
virtual void UpdateAssetManager(std::shared_ptr<AssetManager> asset_manager);
/// If a null resolver is provided, nothing will be done. If no
/// matching resolver is found, the provided resolver will be
/// added to the end of the AssetManager resolvers queue. The
/// replacement only occurs with the first matching resolver.
/// Any additional matching resolvers are untouched.
///
/// @param[in] updated_asset_resolver The asset resolver to replace the
/// resolver of matching type with.
///
/// @param[in] type The type of AssetResolver to update. Only resolvers of
/// the specified type will be replaced by the updated
/// resolver.
///
virtual void UpdateAssetResolverByType(
std::unique_ptr<AssetResolver> updated_asset_resolver,
AssetResolver::AssetResolverType type);
protected:
PlatformView::Delegate& delegate_;

View File

@ -1225,8 +1225,11 @@ void Shell::LoadDartDeferredLibraryError(intptr_t loading_unit_id,
transient);
}
void Shell::UpdateAssetManager(std::shared_ptr<AssetManager> asset_manager) {
engine_->UpdateAssetManager(std::move(asset_manager));
void Shell::UpdateAssetResolverByType(
std::unique_ptr<AssetResolver> updated_asset_resolver,
AssetResolver::AssetResolverType type) {
engine_->GetAssetManager()->UpdateResolverByType(
std::move(updated_asset_resolver), type);
}
// |Engine::Delegate|

View File

@ -536,7 +536,9 @@ class Shell final : public PlatformView::Delegate,
bool transient) override;
// |PlatformView::Delegate|
void UpdateAssetManager(std::shared_ptr<AssetManager> asset_manager) override;
void UpdateAssetResolverByType(
std::unique_ptr<AssetResolver> updated_asset_resolver,
AssetResolver::AssetResolverType type) override;
// |Animator::Delegate|
void OnAnimatorBeginFrame(fml::TimePoint frame_target_time) override;

View File

@ -9,6 +9,7 @@
#include <functional>
#include <future>
#include <memory>
#include <vector>
#include "assets/directory_asset_bundle.h"
#include "flutter/common/graphics/persistent_cache.h"
@ -88,8 +89,9 @@ class MockPlatformViewDelegate : public PlatformView::Delegate {
const std::string error_message,
bool transient));
MOCK_METHOD1(UpdateAssetManager,
void(std::shared_ptr<AssetManager> asset_manager));
MOCK_METHOD2(UpdateAssetResolverByType,
void(std::unique_ptr<AssetResolver> updated_asset_resolver,
AssetResolver::AssetResolverType type));
};
class MockSurface : public Surface {
@ -115,6 +117,33 @@ class MockPlatformView : public PlatformView {
};
} // namespace
class TestAssetResolver : public AssetResolver {
public:
TestAssetResolver(bool valid, AssetResolver::AssetResolverType type)
: valid_(valid), type_(type) {}
bool IsValid() const override { return true; }
// This is used to identify if replacement was made or not.
bool IsValidAfterAssetManagerChange() const override { return valid_; }
AssetResolver::AssetResolverType GetType() const override { return type_; }
std::unique_ptr<fml::Mapping> GetAsMapping(
const std::string& asset_name) const override {
return nullptr;
}
std::vector<std::unique_ptr<fml::Mapping>> GetAsMappings(
const std::string& asset_pattern) const override {
return {};
};
private:
bool valid_;
AssetResolver::AssetResolverType type_;
};
static bool ValidateShell(Shell* shell) {
if (!shell) {
return false;
@ -2437,5 +2466,165 @@ TEST_F(ShellTest, Spawn) {
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}
TEST_F(ShellTest, UpdateAssetResolverByTypeReplaces) {
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
Settings settings = CreateSettingsForFixture();
ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
ThreadHost::Type::Platform);
auto task_runner = thread_host.platform_thread->GetTaskRunner();
TaskRunners task_runners("test", task_runner, task_runner, task_runner,
task_runner);
auto shell = CreateShell(std::move(settings), task_runners);
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
ASSERT_TRUE(ValidateShell(shell.get()));
auto configuration = RunConfiguration::InferFromSettings(settings);
configuration.SetEntrypoint("emptyMain");
auto asset_manager = configuration.GetAssetManager();
RunEngine(shell.get(), std::move(configuration));
auto platform_view =
std::make_unique<PlatformView>(*shell.get(), std::move(task_runners));
auto old_resolver = std::make_unique<TestAssetResolver>(
true, AssetResolver::AssetResolverType::kApkAssetProvider);
ASSERT_TRUE(old_resolver->IsValid());
asset_manager->PushBack(std::move(old_resolver));
auto updated_resolver = std::make_unique<TestAssetResolver>(
false, AssetResolver::AssetResolverType::kApkAssetProvider);
ASSERT_FALSE(updated_resolver->IsValidAfterAssetManagerChange());
platform_view->UpdateAssetResolverByType(
std::move(updated_resolver),
AssetResolver::AssetResolverType::kApkAssetProvider);
auto resolvers = asset_manager->TakeResolvers();
ASSERT_EQ(resolvers.size(), 2ull);
ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
ASSERT_FALSE(resolvers[1]->IsValidAfterAssetManagerChange());
DestroyShell(std::move(shell), std::move(task_runners));
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}
TEST_F(ShellTest, UpdateAssetResolverByTypeAppends) {
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
Settings settings = CreateSettingsForFixture();
ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
ThreadHost::Type::Platform);
auto task_runner = thread_host.platform_thread->GetTaskRunner();
TaskRunners task_runners("test", task_runner, task_runner, task_runner,
task_runner);
auto shell = CreateShell(std::move(settings), task_runners);
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
ASSERT_TRUE(ValidateShell(shell.get()));
auto configuration = RunConfiguration::InferFromSettings(settings);
configuration.SetEntrypoint("emptyMain");
auto asset_manager = configuration.GetAssetManager();
RunEngine(shell.get(), std::move(configuration));
auto platform_view =
std::make_unique<PlatformView>(*shell.get(), std::move(task_runners));
auto updated_resolver = std::make_unique<TestAssetResolver>(
false, AssetResolver::AssetResolverType::kApkAssetProvider);
ASSERT_FALSE(updated_resolver->IsValidAfterAssetManagerChange());
platform_view->UpdateAssetResolverByType(
std::move(updated_resolver),
AssetResolver::AssetResolverType::kApkAssetProvider);
auto resolvers = asset_manager->TakeResolvers();
ASSERT_EQ(resolvers.size(), 2ull);
ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
ASSERT_FALSE(resolvers[1]->IsValidAfterAssetManagerChange());
DestroyShell(std::move(shell), std::move(task_runners));
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}
TEST_F(ShellTest, UpdateAssetResolverByTypeNull) {
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
Settings settings = CreateSettingsForFixture();
ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
ThreadHost::Type::Platform);
auto task_runner = thread_host.platform_thread->GetTaskRunner();
TaskRunners task_runners("test", task_runner, task_runner, task_runner,
task_runner);
auto shell = CreateShell(std::move(settings), task_runners);
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
ASSERT_TRUE(ValidateShell(shell.get()));
auto configuration = RunConfiguration::InferFromSettings(settings);
configuration.SetEntrypoint("emptyMain");
auto asset_manager = configuration.GetAssetManager();
RunEngine(shell.get(), std::move(configuration));
auto platform_view =
std::make_unique<PlatformView>(*shell.get(), std::move(task_runners));
auto old_resolver = std::make_unique<TestAssetResolver>(
true, AssetResolver::AssetResolverType::kApkAssetProvider);
ASSERT_TRUE(old_resolver->IsValid());
asset_manager->PushBack(std::move(old_resolver));
platform_view->UpdateAssetResolverByType(
std::move(nullptr), AssetResolver::AssetResolverType::kApkAssetProvider);
auto resolvers = asset_manager->TakeResolvers();
ASSERT_EQ(resolvers.size(), 2ull);
ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
ASSERT_TRUE(resolvers[1]->IsValidAfterAssetManagerChange());
DestroyShell(std::move(shell), std::move(task_runners));
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}
TEST_F(ShellTest, UpdateAssetResolverByTypeDoesNotReplaceMismatchType) {
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
Settings settings = CreateSettingsForFixture();
ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
ThreadHost::Type::Platform);
auto task_runner = thread_host.platform_thread->GetTaskRunner();
TaskRunners task_runners("test", task_runner, task_runner, task_runner,
task_runner);
auto shell = CreateShell(std::move(settings), task_runners);
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
ASSERT_TRUE(ValidateShell(shell.get()));
auto configuration = RunConfiguration::InferFromSettings(settings);
configuration.SetEntrypoint("emptyMain");
auto asset_manager = configuration.GetAssetManager();
RunEngine(shell.get(), std::move(configuration));
auto platform_view =
std::make_unique<PlatformView>(*shell.get(), std::move(task_runners));
auto old_resolver = std::make_unique<TestAssetResolver>(
true, AssetResolver::AssetResolverType::kAssetManager);
ASSERT_TRUE(old_resolver->IsValid());
asset_manager->PushBack(std::move(old_resolver));
auto updated_resolver = std::make_unique<TestAssetResolver>(
false, AssetResolver::AssetResolverType::kApkAssetProvider);
ASSERT_FALSE(updated_resolver->IsValidAfterAssetManagerChange());
platform_view->UpdateAssetResolverByType(
std::move(updated_resolver),
AssetResolver::AssetResolverType::kApkAssetProvider);
auto resolvers = asset_manager->TakeResolvers();
ASSERT_EQ(resolvers.size(), 3ull);
ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
ASSERT_TRUE(resolvers[1]->IsValidAfterAssetManagerChange());
ASSERT_FALSE(resolvers[2]->IsValidAfterAssetManagerChange());
DestroyShell(std::move(shell), std::move(task_runners));
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}
} // namespace testing
} // namespace flutter

View File

@ -31,6 +31,11 @@ bool APKAssetProvider::IsValidAfterAssetManagerChange() const {
return true;
}
// |AssetResolver|
AssetResolver::AssetResolverType APKAssetProvider::GetType() const {
return AssetResolver::AssetResolverType::kApkAssetProvider;
}
class APKAssetMapping : public fml::Mapping {
public:
APKAssetMapping(AAsset* asset) : asset_(asset) {}

View File

@ -32,6 +32,9 @@ class APKAssetProvider final : public AssetResolver {
// |flutter::AssetResolver|
bool IsValidAfterAssetManagerChange() const override;
// |AssetResolver|
AssetResolver::AssetResolverType GetType() const override;
// |flutter::AssetResolver|
std::unique_ptr<fml::Mapping> GetAsMapping(
const std::string& asset_name) const override;

View File

@ -1056,14 +1056,14 @@ public class FlutterJNI {
* value is `flutter_assets`.
*/
@UiThread
public void updateAssetManager(
public void updateJavaAssetManager(
@NonNull AssetManager assetManager, @NonNull String assetBundlePath) {
ensureRunningOnMainThread();
ensureAttachedToNative();
nativeUpdateAssetManager(nativePlatformViewId, assetManager, assetBundlePath);
nativeUpdateJavaAssetManager(nativePlatformViewId, assetManager, assetBundlePath);
}
private native void nativeUpdateAssetManager(
private native void nativeUpdateJavaAssetManager(
long nativePlatformViewId,
@NonNull AssetManager assetManager,
@NonNull String assetBundlePath);

View File

@ -317,7 +317,7 @@ public class PlayStoreDynamicFeatureManager implements DynamicFeatureManager {
context = context.createPackageContext(context.getPackageName(), 0);
AssetManager assetManager = context.getAssets();
flutterJNI.updateAssetManager(
flutterJNI.updateJavaAssetManager(
assetManager,
// TODO(garyq): Made the "flutter_assets" directory dynamic based off of DartEntryPoint.
"flutter_assets");

View File

@ -363,9 +363,10 @@ void PlatformViewAndroid::LoadDartDeferredLibraryError(
}
// |PlatformView|
void PlatformViewAndroid::UpdateAssetManager(
std::shared_ptr<AssetManager> asset_manager) {
delegate_.UpdateAssetManager(std::move(asset_manager));
void PlatformViewAndroid::UpdateAssetResolverByType(
std::unique_ptr<AssetResolver> updated_asset_resolver,
AssetResolver::AssetResolverType type) {
delegate_.UpdateAssetResolverByType(std::move(updated_asset_resolver), type);
}
void PlatformViewAndroid::InstallFirstFrameCallback() {

View File

@ -104,7 +104,9 @@ class PlatformViewAndroid final : public PlatformView {
bool transient) override;
// |PlatformView|
void UpdateAssetManager(std::shared_ptr<AssetManager> asset_manager) override;
void UpdateAssetResolverByType(
std::unique_ptr<AssetResolver> updated_asset_resolver,
AssetResolver::AssetResolverType type) override;
private:
const std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;

View File

@ -571,24 +571,19 @@ static void LoadDartDeferredLibrary(JNIEnv* env,
std::move(instructions_mapping));
}
// TODO(garyq): persist additional asset resolvers by updating instead of
// replacing with newly created asset_manager
static void UpdateAssetManager(JNIEnv* env,
jobject obj,
jlong shell_holder,
jobject jAssetManager,
jstring jAssetBundlePath) {
auto asset_manager = std::make_shared<flutter::AssetManager>();
asset_manager->PushBack(std::make_unique<flutter::APKAssetProvider>(
env, // jni environment
jAssetManager, // asset manager
fml::jni::JavaStringToString(env, jAssetBundlePath)) // apk asset dir
);
// Create config to set persistent cache asset manager
RunConfiguration config(nullptr, std::move(asset_manager));
static void UpdateJavaAssetManager(JNIEnv* env,
jobject obj,
jlong shell_holder,
jobject jAssetManager,
jstring jAssetBundlePath) {
auto asset_resolver = std::make_unique<flutter::APKAssetProvider>(
env, // jni environment
jAssetManager, // asset manager
fml::jni::JavaStringToString(env, jAssetBundlePath)); // apk asset dir
ANDROID_SHELL_HOLDER->GetPlatformView()->UpdateAssetManager(
config.GetAssetManager());
ANDROID_SHELL_HOLDER->GetPlatformView()->UpdateAssetResolverByType(
std::move(asset_resolver),
AssetResolver::AssetResolverType::kApkAssetProvider);
}
bool RegisterApi(JNIEnv* env) {
@ -753,10 +748,10 @@ bool RegisterApi(JNIEnv* env) {
.fnPtr = reinterpret_cast<void*>(&LoadDartDeferredLibrary),
},
{
.name = "nativeUpdateAssetManager",
.name = "nativeUpdateJavaAssetManager",
.signature =
"(JLandroid/content/res/AssetManager;Ljava/lang/String;)V",
.fnPtr = reinterpret_cast<void*>(&UpdateAssetManager),
.fnPtr = reinterpret_cast<void*>(&UpdateJavaAssetManager),
},
{
.name = "nativeDynamicFeatureInstallFailure",

View File

@ -44,7 +44,7 @@ public class PlayStoreDynamicFeatureManagerTest {
}
@Override
public void updateAssetManager(
public void updateJavaAssetManager(
@NonNull AssetManager assetManager, @NonNull String assetBundlePath) {
updateAssetManagerCalled++;
this.loadingUnitId = loadingUnitId;

View File

@ -41,7 +41,8 @@ class MockDelegate : public PlatformView::Delegate {
void LoadDartDeferredLibraryError(intptr_t loading_unit_id,
const std::string error_message,
bool transient) override {}
void UpdateAssetManager(std::shared_ptr<AssetManager> asset_manager) override {}
void UpdateAssetResolverByType(std::unique_ptr<AssetResolver> updated_asset_resolver,
AssetResolver::AssetResolverType type) override {}
};
} // namespace

View File

@ -111,7 +111,8 @@ class FlutterPlatformViewsTestMockPlatformViewDelegate : public PlatformView::De
void LoadDartDeferredLibraryError(intptr_t loading_unit_id,
const std::string error_message,
bool transient) override {}
void UpdateAssetManager(std::shared_ptr<AssetManager> asset_manager) override {}
void UpdateAssetResolverByType(std::unique_ptr<flutter::AssetResolver> updated_asset_resolver,
flutter::AssetResolver::AssetResolverType type) override {}
};
} // namespace

View File

@ -94,7 +94,8 @@ class MockDelegate : public PlatformView::Delegate {
void LoadDartDeferredLibraryError(intptr_t loading_unit_id,
const std::string error_message,
bool transient) override {}
void UpdateAssetManager(std::shared_ptr<AssetManager> asset_manager) override {}
void UpdateAssetResolverByType(std::unique_ptr<flutter::AssetResolver> updated_asset_resolver,
flutter::AssetResolver::AssetResolverType type) override {}
};
class MockIosDelegate : public AccessibilityBridge::IosDelegate {

View File

@ -114,8 +114,9 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate {
const std::string error_message,
bool transient) {}
// |flutter::PlatformView::Delegate|
void UpdateAssetManager(
std::shared_ptr<flutter::AssetManager> asset_manager) {}
void UpdateAssetResolverByType(
std::unique_ptr<flutter::AssetResolver> updated_asset_resolver,
flutter::AssetResolver::AssetResolverType type) {}
flutter::Surface* surface() const { return surface_.get(); }
flutter::PlatformMessage* message() const { return message_.get(); }