From d870deabd056f1bee34a889f86d97cbf3d2c2dd2 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Sat, 26 Sep 2020 09:59:36 -0700 Subject: [PATCH 01/12] Allow hot reload without syncing all asset files to devFS --- assets/asset_manager.cc | 9 +++++++++ assets/asset_manager.h | 2 ++ shell/common/engine.cc | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/assets/asset_manager.cc b/assets/asset_manager.cc index 60d169a31ebb2..de98183db1637 100644 --- a/assets/asset_manager.cc +++ b/assets/asset_manager.cc @@ -29,6 +29,15 @@ void AssetManager::PushBack(std::unique_ptr resolver) { resolvers_.push_back(std::move(resolver)); } +void AssetManager::Merge(std::shared_ptr assetManager) { + if (assetManager == nullptr) { + return; + } + for (int i = 0; i < assetManager->resolvers_.size(); i++) { + resolvers_.push_back(std::move(assetManager->resolvers_[i])); + } +} + // |AssetResolver| std::unique_ptr AssetManager::GetAsMapping( const std::string& asset_name) const { diff --git a/assets/asset_manager.h b/assets/asset_manager.h index 2278742f50113..80a853330b82b 100644 --- a/assets/asset_manager.h +++ b/assets/asset_manager.h @@ -25,6 +25,8 @@ class AssetManager final : public AssetResolver { void PushBack(std::unique_ptr resolver); + void Merge(std::shared_ptr assetManager); + // |AssetResolver| bool IsValid() const override; diff --git a/shell/common/engine.cc b/shell/common/engine.cc index d2384c03579cf..6e4415d398ae6 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -111,7 +111,7 @@ bool Engine::UpdateAssetManager( if (asset_manager_ == new_asset_manager) { return false; } - + new_asset_manager->Merge(asset_manager_); asset_manager_ = new_asset_manager; if (!asset_manager_) { From 847b53de99c7a38d5d72ca98d40e54b18d4da80d Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Sat, 26 Sep 2020 10:16:48 -0700 Subject: [PATCH 02/12] Update asset_manager.cc --- assets/asset_manager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/asset_manager.cc b/assets/asset_manager.cc index de98183db1637..53b4896ec90cb 100644 --- a/assets/asset_manager.cc +++ b/assets/asset_manager.cc @@ -33,7 +33,7 @@ void AssetManager::Merge(std::shared_ptr assetManager) { if (assetManager == nullptr) { return; } - for (int i = 0; i < assetManager->resolvers_.size(); i++) { + for (auto i = 0; i < assetManager->resolvers_.size(); i++) { resolvers_.push_back(std::move(assetManager->resolvers_[i])); } } From 62cea76cccfbfbc0592405b9db20ed71ecaf5394 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Sat, 26 Sep 2020 17:10:47 -0700 Subject: [PATCH 03/12] only preserve original asset manager --- assets/asset_manager.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/asset_manager.cc b/assets/asset_manager.cc index 53b4896ec90cb..c61ab852012d5 100644 --- a/assets/asset_manager.cc +++ b/assets/asset_manager.cc @@ -33,8 +33,8 @@ void AssetManager::Merge(std::shared_ptr assetManager) { if (assetManager == nullptr) { return; } - for (auto i = 0; i < assetManager->resolvers_.size(); i++) { - resolvers_.push_back(std::move(assetManager->resolvers_[i])); + if (assetManager->resolvers_.size() > 0) { + resolvers_.push_back(std::move(assetManager->resolvers_[assetManager->resolvers_.size() - 1])); } } From ec3ba29fbf8d81dbfaad79a9cd41e3495c9b5c22 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Sat, 26 Sep 2020 17:18:10 -0700 Subject: [PATCH 04/12] Update asset_manager.cc --- assets/asset_manager.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/asset_manager.cc b/assets/asset_manager.cc index c61ab852012d5..7beb891295c13 100644 --- a/assets/asset_manager.cc +++ b/assets/asset_manager.cc @@ -34,7 +34,8 @@ void AssetManager::Merge(std::shared_ptr assetManager) { return; } if (assetManager->resolvers_.size() > 0) { - resolvers_.push_back(std::move(assetManager->resolvers_[assetManager->resolvers_.size() - 1])); + resolvers_.push_back(std::move( + assetManager->resolvers_[assetManager->resolvers_.size() - 1])); } } From 9ebdec9a81fc5fb6581f00852ae98378a0b9f9ed Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Sun, 27 Sep 2020 17:41:49 -0700 Subject: [PATCH 05/12] Update engine.cc --- shell/common/engine.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 6e4415d398ae6..6be27e56213e2 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -111,12 +111,13 @@ bool Engine::UpdateAssetManager( if (asset_manager_ == new_asset_manager) { return false; } - new_asset_manager->Merge(asset_manager_); + auto old_asset_manager = asset_manager_; asset_manager_ = new_asset_manager; if (!asset_manager_) { return false; } + asset_manager_->Merge(old_asset_manager); // Using libTXT as the text engine. font_collection_.RegisterFonts(asset_manager_); From 262912a62f275c5f7900b38b24b218949106386e Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 29 Sep 2020 19:40:38 -0700 Subject: [PATCH 06/12] always re-create original asset dir --- assets/asset_manager.cc | 9 --------- assets/asset_manager.h | 2 -- shell/common/engine.cc | 1 - shell/common/shell.cc | 6 ++++++ 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/assets/asset_manager.cc b/assets/asset_manager.cc index c61ab852012d5..60d169a31ebb2 100644 --- a/assets/asset_manager.cc +++ b/assets/asset_manager.cc @@ -29,15 +29,6 @@ void AssetManager::PushBack(std::unique_ptr resolver) { resolvers_.push_back(std::move(resolver)); } -void AssetManager::Merge(std::shared_ptr assetManager) { - if (assetManager == nullptr) { - return; - } - if (assetManager->resolvers_.size() > 0) { - resolvers_.push_back(std::move(assetManager->resolvers_[assetManager->resolvers_.size() - 1])); - } -} - // |AssetResolver| std::unique_ptr AssetManager::GetAsMapping( const std::string& asset_name) const { diff --git a/assets/asset_manager.h b/assets/asset_manager.h index 80a853330b82b..2278742f50113 100644 --- a/assets/asset_manager.h +++ b/assets/asset_manager.h @@ -25,8 +25,6 @@ class AssetManager final : public AssetResolver { void PushBack(std::unique_ptr resolver); - void Merge(std::shared_ptr assetManager); - // |AssetResolver| bool IsValid() const override; diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 6e4415d398ae6..eb48ed3dbead4 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -111,7 +111,6 @@ bool Engine::UpdateAssetManager( if (asset_manager_ == new_asset_manager) { return false; } - new_asset_manager->Merge(asset_manager_); asset_manager_ = new_asset_manager; if (!asset_manager_) { diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 1503519ca7f4d..1e6e350ab3712 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1401,6 +1401,9 @@ bool Shell::OnServiceProtocolRunInView( configuration.SetEntrypointAndLibrary(engine_->GetLastEntrypoint(), engine_->GetLastEntrypointLibrary()); + configuration.AddAssetResolver( + std::make_unique(fml::OpenDirectory( + settings_.assets_path.c_str(), false, fml::FilePermission::kRead))); configuration.AddAssetResolver( std::make_unique(fml::OpenDirectory( asset_directory_path.c_str(), false, fml::FilePermission::kRead))); @@ -1516,6 +1519,9 @@ bool Shell::OnServiceProtocolSetAssetBundlePath( auto asset_manager = std::make_shared(); + asset_manager->PushFront( + std::make_unique(fml::OpenDirectory( + settings_.assets_path.c_str(), false, fml::FilePermission::kRead))); asset_manager->PushFront(std::make_unique( fml::OpenDirectory(params.at("assetDirectory").data(), false, fml::FilePermission::kRead))); From 5a954125c4cea6773beb1046534c2e03d847fab0 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 29 Sep 2020 19:42:30 -0700 Subject: [PATCH 07/12] remove missed merge --- shell/common/engine.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 713d46f1f11b5..d2384c03579cf 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -111,12 +111,12 @@ bool Engine::UpdateAssetManager( if (asset_manager_ == new_asset_manager) { return false; } + asset_manager_ = new_asset_manager; if (!asset_manager_) { return false; } - asset_manager_->Merge(old_asset_manager); // Using libTXT as the text engine. font_collection_.RegisterFonts(asset_manager_); From cb3e7b1269460ede9e1b313b72c83015a4ec13fb Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 29 Sep 2020 19:43:35 -0700 Subject: [PATCH 08/12] fix order of asset resolvers --- shell/common/shell.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 1e6e350ab3712..a73dcbc1a9898 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1403,10 +1403,10 @@ bool Shell::OnServiceProtocolRunInView( configuration.AddAssetResolver( std::make_unique(fml::OpenDirectory( - settings_.assets_path.c_str(), false, fml::FilePermission::kRead))); + asset_directory_path.c_str(), false, fml::FilePermission::kRead))); configuration.AddAssetResolver( std::make_unique(fml::OpenDirectory( - asset_directory_path.c_str(), false, fml::FilePermission::kRead))); + settings_.assets_path.c_str(), false, fml::FilePermission::kRead))); auto& allocator = response->GetAllocator(); response->SetObject(); From 32f85bdc7d875d878e6e99866332d3ade9667d49 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 1 Oct 2020 12:22:27 -0700 Subject: [PATCH 09/12] add shell unit test for setting asset dir path --- shell/common/fixtures/shell_test.dart | 16 +++++++++ shell/common/shell.cc | 28 +++++++++++---- shell/common/shell_unittests.cc | 49 +++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 6 deletions(-) diff --git a/shell/common/fixtures/shell_test.dart b/shell/common/fixtures/shell_test.dart index 75fad7e109283..492ddb8960d03 100644 --- a/shell/common/fixtures/shell_test.dart +++ b/shell/common/fixtures/shell_test.dart @@ -163,3 +163,19 @@ void localtimesMatch() { // formatting since package:intl is not available. notifyLocalTime(timeStr.split(":")[0]); } + +void notifyCanAccessResource(bool success) native 'NotifyCanAccessResource'; + +void notifySetAssetBundlePath() native 'NotifySetAssetBundlePath'; + +@pragma('vm:entry-point') +void canAccessResourceFromAssetDir() async { + notifySetAssetBundlePath(); + window.sendPlatformMessage( + 'flutter/assets', + Uint8List.fromList(utf8.encode('kernel_blob.bin')).buffer.asByteData(), + (ByteData byteData) { + notifyCanAccessResource(byteData != null); + }, + ); +} diff --git a/shell/common/shell.cc b/shell/common/shell.cc index a73dcbc1a9898..00c863cddff3e 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1404,9 +1404,17 @@ bool Shell::OnServiceProtocolRunInView( configuration.AddAssetResolver( std::make_unique(fml::OpenDirectory( asset_directory_path.c_str(), false, fml::FilePermission::kRead))); - configuration.AddAssetResolver( - std::make_unique(fml::OpenDirectory( - settings_.assets_path.c_str(), false, fml::FilePermission::kRead))); + // Add the original asset directory to the resolvers so that unmodified assets + // bundled with the application specific format (APK, IPA) can be used without + // syncing to the Dart devFS. + if (fml::UniqueFD::traits_type::IsValid(settings_.assets_dir)) { + configuration.AddAssetResolver(std::make_unique( + fml::Duplicate(settings_.assets_dir))); + } else { + configuration.AddAssetResolver( + std::make_unique(fml::OpenDirectory( + settings_.assets_path.c_str(), false, fml::FilePermission::kRead))); + } auto& allocator = response->GetAllocator(); response->SetObject(); @@ -1519,9 +1527,17 @@ bool Shell::OnServiceProtocolSetAssetBundlePath( auto asset_manager = std::make_shared(); - asset_manager->PushFront( - std::make_unique(fml::OpenDirectory( - settings_.assets_path.c_str(), false, fml::FilePermission::kRead))); + // Add the original asset directory to the resolvers so that unmodified assets + // bundled with the application specific format (APK, IPA) can be used without + // syncing to the Dart devFS. + if (fml::UniqueFD::traits_type::IsValid(settings_.assets_dir)) { + asset_manager->PushFront(std::make_unique( + fml::Duplicate(settings_.assets_dir))); + } else { + asset_manager->PushFront( + std::make_unique(fml::OpenDirectory( + settings_.assets_path.c_str(), false, fml::FilePermission::kRead))); + } asset_manager->PushFront(std::make_unique( fml::OpenDirectory(params.at("assetDirectory").data(), false, fml::FilePermission::kRead))); diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 2e708d0cbc612..fbf0647eb1191 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -2135,5 +2135,54 @@ TEST_F(ShellTest, IgnoresInvalidMetrics) { DestroyShell(std::move(shell), std::move(task_runners)); } +TEST_F(ShellTest, OnServiceProtocolSetAssetBundlePathWorks) { + Settings settings = CreateSettingsForFixture(); + std::unique_ptr shell = CreateShell(settings); + RunConfiguration configuration = + RunConfiguration::InferFromSettings(settings); + configuration.SetEntrypoint("canAccessResourceFromAssetDir"); + + // Verify isolate can load a known resource with the + // default asset directory - kernel_blob.bin + fml::AutoResetWaitableEvent latch; + + // Callback used to signal whether the resource was loaded successfully. + bool can_access_resource = false; + auto native_can_access_resource = [&can_access_resource, + &latch](Dart_NativeArguments args) { + Dart_Handle exception = nullptr; + can_access_resource = + tonic::DartConverter::FromArguments(args, 0, exception); + latch.Signal(); + }; + AddNativeCallback("NotifyCanAccessResource", + CREATE_NATIVE_ENTRY(native_can_access_resource)); + + // Callback used to delay the asset load until after the service + // protocol method has finished. + auto native_notify_set_asset_bundle_path = + [&shell](Dart_NativeArguments args) { + // Update the asset directory to a bonus path. + ServiceProtocol::Handler::ServiceProtocolMap params; + params["assetDirectory"] = "assetDirectory"; + rapidjson::Document document; + OnServiceProtocol(shell.get(), ServiceProtocolEnum::kSetAssetBundlePath, + shell->GetTaskRunners().GetUITaskRunner(), params, + &document); + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + document.Accept(writer); + }; + AddNativeCallback("NotifySetAssetBundlePath", + CREATE_NATIVE_ENTRY(native_notify_set_asset_bundle_path)); + + RunEngine(shell.get(), std::move(configuration)); + + latch.Wait(); + ASSERT_TRUE(can_access_resource); + + DestroyShell(std::move(shell)); +} + } // namespace testing } // namespace flutter From f42dd5ef0d65c6d520765a0fd850866c5bca76af Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 2 Oct 2020 11:50:22 -0700 Subject: [PATCH 10/12] maybe this works --- shell/common/shell.cc | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 00c863cddff3e..d68c555b33e03 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -40,6 +40,19 @@ constexpr char kSystemChannel[] = "flutter/system"; constexpr char kTypeKey[] = "type"; constexpr char kFontChange[] = "fontsChange"; +// Add the original asset directory to the resolvers so that unmodified assets +// bundled with the application specific format (APK, IPA) can be used without +// syncing to the Dart devFS. +std::unique_ptr restoreOriginalAssetResolver( + const Settings& settings) { + if (fml::UniqueFD::traits_type::IsValid(settings.assets_dir)) { + return std::make_unique( + fml::Duplicate(settings.assets_dir)); + } + return std::make_unique(fml::OpenDirectory( + settings.assets_path.c_str(), false, fml::FilePermission::kRead)); +}; + std::unique_ptr Shell::CreateShellOnPlatformThread( DartVMRef vm, TaskRunners task_runners, @@ -1404,17 +1417,7 @@ bool Shell::OnServiceProtocolRunInView( configuration.AddAssetResolver( std::make_unique(fml::OpenDirectory( asset_directory_path.c_str(), false, fml::FilePermission::kRead))); - // Add the original asset directory to the resolvers so that unmodified assets - // bundled with the application specific format (APK, IPA) can be used without - // syncing to the Dart devFS. - if (fml::UniqueFD::traits_type::IsValid(settings_.assets_dir)) { - configuration.AddAssetResolver(std::make_unique( - fml::Duplicate(settings_.assets_dir))); - } else { - configuration.AddAssetResolver( - std::make_unique(fml::OpenDirectory( - settings_.assets_path.c_str(), false, fml::FilePermission::kRead))); - } + configuration.AddAssetResolver(restoreOriginalAssetResolver(settings_)); auto& allocator = response->GetAllocator(); response->SetObject(); @@ -1527,17 +1530,7 @@ bool Shell::OnServiceProtocolSetAssetBundlePath( auto asset_manager = std::make_shared(); - // Add the original asset directory to the resolvers so that unmodified assets - // bundled with the application specific format (APK, IPA) can be used without - // syncing to the Dart devFS. - if (fml::UniqueFD::traits_type::IsValid(settings_.assets_dir)) { - asset_manager->PushFront(std::make_unique( - fml::Duplicate(settings_.assets_dir))); - } else { - asset_manager->PushFront( - std::make_unique(fml::OpenDirectory( - settings_.assets_path.c_str(), false, fml::FilePermission::kRead))); - } + asset_manager->PushFront(restoreOriginalAssetResolver(settings_)); asset_manager->PushFront(std::make_unique( fml::OpenDirectory(params.at("assetDirectory").data(), false, fml::FilePermission::kRead))); From f0043373b9453ac5a817d871051ce0c8f9fcf96a Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 2 Oct 2020 12:20:41 -0700 Subject: [PATCH 11/12] make a private member --- shell/common/shell.cc | 30 +++++++++++++++--------------- shell/common/shell.h | 5 +++++ 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index d68c555b33e03..99e1951f668a4 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -40,19 +40,6 @@ constexpr char kSystemChannel[] = "flutter/system"; constexpr char kTypeKey[] = "type"; constexpr char kFontChange[] = "fontsChange"; -// Add the original asset directory to the resolvers so that unmodified assets -// bundled with the application specific format (APK, IPA) can be used without -// syncing to the Dart devFS. -std::unique_ptr restoreOriginalAssetResolver( - const Settings& settings) { - if (fml::UniqueFD::traits_type::IsValid(settings.assets_dir)) { - return std::make_unique( - fml::Duplicate(settings.assets_dir)); - } - return std::make_unique(fml::OpenDirectory( - settings.assets_path.c_str(), false, fml::FilePermission::kRead)); -}; - std::unique_ptr Shell::CreateShellOnPlatformThread( DartVMRef vm, TaskRunners task_runners, @@ -1417,7 +1404,7 @@ bool Shell::OnServiceProtocolRunInView( configuration.AddAssetResolver( std::make_unique(fml::OpenDirectory( asset_directory_path.c_str(), false, fml::FilePermission::kRead))); - configuration.AddAssetResolver(restoreOriginalAssetResolver(settings_)); + configuration.AddAssetResolver(RestoreOriginalAssetResolver()); auto& allocator = response->GetAllocator(); response->SetObject(); @@ -1530,7 +1517,7 @@ bool Shell::OnServiceProtocolSetAssetBundlePath( auto asset_manager = std::make_shared(); - asset_manager->PushFront(restoreOriginalAssetResolver(settings_)); + asset_manager->PushFront(RestoreOriginalAssetResolver()); asset_manager->PushFront(std::make_unique( fml::OpenDirectory(params.at("assetDirectory").data(), false, fml::FilePermission::kRead))); @@ -1637,4 +1624,17 @@ void Shell::OnDisplayUpdates(DisplayUpdateType update_type, display_manager_->HandleDisplayUpdates(update_type, displays); } +// Add the original asset directory to the resolvers so that unmodified assets +// bundled with the application specific format (APK, IPA) can be used without +// syncing to the Dart devFS. +std::unique_ptr Shell::RestoreOriginalAssetResolver() { + if (fml::UniqueFD::traits_type::IsValid(settings_.assets_dir)) { + return std::make_unique( + fml::Duplicate(settings_.assets_dir)); + } + return std::make_unique(fml::OpenDirectory( + settings_.assets_path.c_str(), false, fml::FilePermission::kRead)); +}; + + } // namespace flutter diff --git a/shell/common/shell.h b/shell/common/shell.h index 74ad1c280e3ae..a345b0461e5fc 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -10,6 +10,7 @@ #include #include +#include "flutter/assets/directory_asset_bundle.h" #include "flutter/common/settings.h" #include "flutter/common/task_runners.h" #include "flutter/flow/surface.h" @@ -612,6 +613,10 @@ class Shell final : public PlatformView::Delegate, const ServiceProtocol::Handler::ServiceProtocolMap& params, rapidjson::Document* response); + // Creates an asset bundle from the original settings asset path or + // directory. + std::unique_ptr RestoreOriginalAssetResolver(); + // For accessing the Shell via the raster thread, necessary for various // rasterizer callbacks. std::unique_ptr> weak_factory_gpu_; From ee6772a7cdba02cc1ef94d2e27b4dc0e73f78a7b Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 2 Oct 2020 13:01:00 -0700 Subject: [PATCH 12/12] format --- shell/common/shell.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 99e1951f668a4..2da9e9786e385 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1636,5 +1636,4 @@ std::unique_ptr Shell::RestoreOriginalAssetResolver() { settings_.assets_path.c_str(), false, fml::FilePermission::kRead)); }; - } // namespace flutter