mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
AssetResolver updating in AssetManager for Dynamic features (flutter/engine#23130)
This commit is contained in:
parent
0bc19d5759
commit
2bfbb4197c
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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_;
|
||||
|
||||
@ -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|
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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_;
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -44,7 +44,7 @@ public class PlayStoreDynamicFeatureManagerTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAssetManager(
|
||||
public void updateJavaAssetManager(
|
||||
@NonNull AssetManager assetManager, @NonNull String assetBundlePath) {
|
||||
updateAssetManagerCalled++;
|
||||
this.loadingUnitId = loadingUnitId;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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(); }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user