From 1c975f1e7c82909bf2a722eee2c4141404be6f3e Mon Sep 17 00:00:00 2001 From: Gary Qian Date: Wed, 23 Dec 2020 18:39:55 -0700 Subject: [PATCH] AssetResolver updating in AssetManager for Dynamic features (#23130) --- assets/asset_manager.cc | 29 +++ assets/asset_manager.h | 31 +++ assets/asset_resolver.h | 17 ++ assets/directory_asset_bundle.cc | 5 + assets/directory_asset_bundle.h | 3 + shell/common/platform_view.cc | 7 +- shell/common/platform_view.h | 69 +++++-- shell/common/shell.cc | 7 +- shell/common/shell.h | 4 +- shell/common/shell_unittests.cc | 193 +++++++++++++++++- shell/platform/android/apk_asset_provider.cc | 5 + shell/platform/android/apk_asset_provider.h | 3 + .../flutter/embedding/engine/FlutterJNI.java | 6 +- .../PlayStoreDynamicFeatureManager.java | 2 +- .../platform/android/platform_view_android.cc | 7 +- .../platform/android/platform_view_android.h | 4 +- .../android/platform_view_android_jni_impl.cc | 35 ++-- .../PlayStoreDynamicFeatureManagerTest.java | 2 +- .../Source/FlutterEnginePlatformViewTest.mm | 3 +- .../Source/FlutterPlatformViewsTest.mm | 3 +- .../Source/accessibility_bridge_test.mm | 3 +- .../fuchsia/flutter/platform_view_unittest.cc | 5 +- 22 files changed, 387 insertions(+), 56 deletions(-) diff --git a/assets/asset_manager.cc b/assets/asset_manager.cc index 31d2131bd05c8..b1c6e04b897f1 100644 --- a/assets/asset_manager.cc +++ b/assets/asset_manager.cc @@ -29,6 +29,30 @@ void AssetManager::PushBack(std::unique_ptr resolver) { resolvers_.push_back(std::move(resolver)); } +void AssetManager::UpdateResolverByType( + std::unique_ptr updated_asset_resolver, + AssetResolver::AssetResolverType type) { + if (updated_asset_resolver == nullptr) { + return; + } + bool updated = false; + std::deque> 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> 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 diff --git a/assets/asset_manager.h b/assets/asset_manager.h index c6fc28657699d..a116d6e906466 100644 --- a/assets/asset_manager.h +++ b/assets/asset_manager.h @@ -25,6 +25,34 @@ class AssetManager final : public AssetResolver { void PushBack(std::unique_ptr 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 updated_asset_resolver, + AssetResolver::AssetResolverType type); + std::deque> 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 GetAsMapping( const std::string& asset_name) const override; diff --git a/assets/asset_resolver.h b/assets/asset_resolver.h index 470ce3864cfff..0674e71121b23 100644 --- a/assets/asset_resolver.h +++ b/assets/asset_resolver.h @@ -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 GetAsMapping( const std::string& asset_name) const = 0; diff --git a/assets/directory_asset_bundle.cc b/assets/directory_asset_bundle.cc index 9c09c00bb4533..45ab571823902 100644 --- a/assets/directory_asset_bundle.cc +++ b/assets/directory_asset_bundle.cc @@ -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 DirectoryAssetBundle::GetAsMapping( const std::string& asset_name) const { diff --git a/assets/directory_asset_bundle.h b/assets/directory_asset_bundle.h index b85ff1dbacad0..b004201e0ad96 100644 --- a/assets/directory_asset_bundle.h +++ b/assets/directory_asset_bundle.h @@ -30,6 +30,9 @@ class DirectoryAssetBundle : public AssetResolver { // |AssetResolver| bool IsValidAfterAssetManagerChange() const override; + // |AssetResolver| + AssetResolver::AssetResolverType GetType() const override; + // |AssetResolver| std::unique_ptr GetAsMapping( const std::string& asset_name) const override; diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index 4205e9853e44f..22c2b395ba76e 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -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 asset_manager) {} +void PlatformView::UpdateAssetResolverByType( + std::unique_ptr updated_asset_resolver, + AssetResolver::AssetResolverType type) { + delegate_.UpdateAssetResolverByType(std::move(updated_asset_resolver), type); +} } // namespace flutter diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 56e3f6af379f2..92e670677c25a 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -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 - /// - /// @param[in] asset_manager The asset manager to use. - /// - virtual void UpdateAssetManager( - std::shared_ptr asset_manager) = 0; + /// @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`. + /// + /// 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. + /// + virtual void UpdateAssetResolverByType( + std::unique_ptr 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 - /// - /// @param[in] asset_manager The asset manager to use. - /// - virtual void UpdateAssetManager(std::shared_ptr 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`. + /// + /// 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. + /// + virtual void UpdateAssetResolverByType( + std::unique_ptr updated_asset_resolver, + AssetResolver::AssetResolverType type); protected: PlatformView::Delegate& delegate_; diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 046f56373601a..a7a50989209ad 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1225,8 +1225,11 @@ void Shell::LoadDartDeferredLibraryError(intptr_t loading_unit_id, transient); } -void Shell::UpdateAssetManager(std::shared_ptr asset_manager) { - engine_->UpdateAssetManager(std::move(asset_manager)); +void Shell::UpdateAssetResolverByType( + std::unique_ptr updated_asset_resolver, + AssetResolver::AssetResolverType type) { + engine_->GetAssetManager()->UpdateResolverByType( + std::move(updated_asset_resolver), type); } // |Engine::Delegate| diff --git a/shell/common/shell.h b/shell/common/shell.h index 503347c39bbd6..024d434d16f36 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -536,7 +536,9 @@ class Shell final : public PlatformView::Delegate, bool transient) override; // |PlatformView::Delegate| - void UpdateAssetManager(std::shared_ptr asset_manager) override; + void UpdateAssetResolverByType( + std::unique_ptr updated_asset_resolver, + AssetResolver::AssetResolverType type) override; // |Animator::Delegate| void OnAnimatorBeginFrame(fml::TimePoint frame_target_time) override; diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index c3b0f13c1be2d..98621f2f0f75e 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -9,6 +9,7 @@ #include #include #include +#include #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 asset_manager)); + MOCK_METHOD2(UpdateAssetResolverByType, + void(std::unique_ptr 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 GetAsMapping( + const std::string& asset_name) const override { + return nullptr; + } + + std::vector> 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(*shell.get(), std::move(task_runners)); + + auto old_resolver = std::make_unique( + true, AssetResolver::AssetResolverType::kApkAssetProvider); + ASSERT_TRUE(old_resolver->IsValid()); + asset_manager->PushBack(std::move(old_resolver)); + + auto updated_resolver = std::make_unique( + 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(*shell.get(), std::move(task_runners)); + + auto updated_resolver = std::make_unique( + 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(*shell.get(), std::move(task_runners)); + + auto old_resolver = std::make_unique( + 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(*shell.get(), std::move(task_runners)); + + auto old_resolver = std::make_unique( + true, AssetResolver::AssetResolverType::kAssetManager); + ASSERT_TRUE(old_resolver->IsValid()); + asset_manager->PushBack(std::move(old_resolver)); + + auto updated_resolver = std::make_unique( + 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 diff --git a/shell/platform/android/apk_asset_provider.cc b/shell/platform/android/apk_asset_provider.cc index 73a4a26bd1d2d..178227e9b156d 100644 --- a/shell/platform/android/apk_asset_provider.cc +++ b/shell/platform/android/apk_asset_provider.cc @@ -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) {} diff --git a/shell/platform/android/apk_asset_provider.h b/shell/platform/android/apk_asset_provider.h index f457b6c4ecc16..d1e7e2f707aab 100644 --- a/shell/platform/android/apk_asset_provider.h +++ b/shell/platform/android/apk_asset_provider.h @@ -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 GetAsMapping( const std::string& asset_name) const override; diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java index 85d49909cea9d..c5a12252f5a3a 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java @@ -1056,14 +1056,14 @@ private native void nativeLoadDartDeferredLibrary( * 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); diff --git a/shell/platform/android/io/flutter/embedding/engine/dynamicfeatures/PlayStoreDynamicFeatureManager.java b/shell/platform/android/io/flutter/embedding/engine/dynamicfeatures/PlayStoreDynamicFeatureManager.java index 2e1b8592a2dd4..41032e13bbaa2 100644 --- a/shell/platform/android/io/flutter/embedding/engine/dynamicfeatures/PlayStoreDynamicFeatureManager.java +++ b/shell/platform/android/io/flutter/embedding/engine/dynamicfeatures/PlayStoreDynamicFeatureManager.java @@ -317,7 +317,7 @@ public void loadAssets(int loadingUnitId, String moduleName) { 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"); diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index 33bf0b4fc3e25..68b2b8fdb1a3f 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -363,9 +363,10 @@ void PlatformViewAndroid::LoadDartDeferredLibraryError( } // |PlatformView| -void PlatformViewAndroid::UpdateAssetManager( - std::shared_ptr asset_manager) { - delegate_.UpdateAssetManager(std::move(asset_manager)); +void PlatformViewAndroid::UpdateAssetResolverByType( + std::unique_ptr updated_asset_resolver, + AssetResolver::AssetResolverType type) { + delegate_.UpdateAssetResolverByType(std::move(updated_asset_resolver), type); } void PlatformViewAndroid::InstallFirstFrameCallback() { diff --git a/shell/platform/android/platform_view_android.h b/shell/platform/android/platform_view_android.h index 19631203365f2..49e3c15c13929 100644 --- a/shell/platform/android/platform_view_android.h +++ b/shell/platform/android/platform_view_android.h @@ -104,7 +104,9 @@ class PlatformViewAndroid final : public PlatformView { bool transient) override; // |PlatformView| - void UpdateAssetManager(std::shared_ptr asset_manager) override; + void UpdateAssetResolverByType( + std::unique_ptr updated_asset_resolver, + AssetResolver::AssetResolverType type) override; private: const std::shared_ptr jni_facade_; diff --git a/shell/platform/android/platform_view_android_jni_impl.cc b/shell/platform/android/platform_view_android_jni_impl.cc index d83c615043332..efe994f52d94b 100644 --- a/shell/platform/android/platform_view_android_jni_impl.cc +++ b/shell/platform/android/platform_view_android_jni_impl.cc @@ -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(); - asset_manager->PushBack(std::make_unique( - 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)); - - ANDROID_SHELL_HOLDER->GetPlatformView()->UpdateAssetManager( - config.GetAssetManager()); +static void UpdateJavaAssetManager(JNIEnv* env, + jobject obj, + jlong shell_holder, + jobject jAssetManager, + jstring jAssetBundlePath) { + auto asset_resolver = std::make_unique( + env, // jni environment + jAssetManager, // asset manager + fml::jni::JavaStringToString(env, jAssetBundlePath)); // apk asset dir + + 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(&LoadDartDeferredLibrary), }, { - .name = "nativeUpdateAssetManager", + .name = "nativeUpdateJavaAssetManager", .signature = "(JLandroid/content/res/AssetManager;Ljava/lang/String;)V", - .fnPtr = reinterpret_cast(&UpdateAssetManager), + .fnPtr = reinterpret_cast(&UpdateJavaAssetManager), }, { .name = "nativeDynamicFeatureInstallFailure", diff --git a/shell/platform/android/test/io/flutter/embedding/engine/dynamicfeatures/PlayStoreDynamicFeatureManagerTest.java b/shell/platform/android/test/io/flutter/embedding/engine/dynamicfeatures/PlayStoreDynamicFeatureManagerTest.java index d6c7bea3c160f..a6d11abfeae44 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/dynamicfeatures/PlayStoreDynamicFeatureManagerTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/dynamicfeatures/PlayStoreDynamicFeatureManagerTest.java @@ -44,7 +44,7 @@ public void loadDartDeferredLibrary(int loadingUnitId, @NonNull String[] searchP } @Override - public void updateAssetManager( + public void updateJavaAssetManager( @NonNull AssetManager assetManager, @NonNull String assetBundlePath) { updateAssetManagerCalled++; this.loadingUnitId = loadingUnitId; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm index 96fb359b96665..c81910f892767 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm @@ -41,7 +41,8 @@ void LoadDartDeferredLibrary(intptr_t loading_unit_id, void LoadDartDeferredLibraryError(intptr_t loading_unit_id, const std::string error_message, bool transient) override {} - void UpdateAssetManager(std::shared_ptr asset_manager) override {} + void UpdateAssetResolverByType(std::unique_ptr updated_asset_resolver, + AssetResolver::AssetResolverType type) override {} }; } // namespace diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index f8b5e4ebc3e7b..8f4b3e7a972c4 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -111,7 +111,8 @@ void LoadDartDeferredLibrary(intptr_t loading_unit_id, void LoadDartDeferredLibraryError(intptr_t loading_unit_id, const std::string error_message, bool transient) override {} - void UpdateAssetManager(std::shared_ptr asset_manager) override {} + void UpdateAssetResolverByType(std::unique_ptr updated_asset_resolver, + flutter::AssetResolver::AssetResolverType type) override {} }; } // namespace diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm index ee56a49a9385d..08f01b7c705ed 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm @@ -94,7 +94,8 @@ void LoadDartDeferredLibrary(intptr_t loading_unit_id, void LoadDartDeferredLibraryError(intptr_t loading_unit_id, const std::string error_message, bool transient) override {} - void UpdateAssetManager(std::shared_ptr asset_manager) override {} + void UpdateAssetResolverByType(std::unique_ptr updated_asset_resolver, + flutter::AssetResolver::AssetResolverType type) override {} }; class MockIosDelegate : public AccessibilityBridge::IosDelegate { diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc index 3222450c04aa3..7fabcbd11d1ba 100644 --- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc @@ -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 asset_manager) {} + void UpdateAssetResolverByType( + std::unique_ptr updated_asset_resolver, + flutter::AssetResolver::AssetResolverType type) {} flutter::Surface* surface() const { return surface_.get(); } flutter::PlatformMessage* message() const { return message_.get(); }