mirror of
https://github.com/encounter/engine.git
synced 2026-03-30 11:09:55 -07:00
Add assets plugin (#3151)
This plugin is implemented internally by the engine to integrate with the asset system.
This commit is contained in:
@@ -54,7 +54,7 @@ deps = {
|
||||
# and not have to specific specific hashes.
|
||||
|
||||
'src/lib/ftl':
|
||||
Var('fuchsia_git') + '/ftl' + '@' + '4917351099cfb11d7bd9a808fd4fce67928c9e40',
|
||||
Var('fuchsia_git') + '/ftl' + '@' + '5e9935c7205c119ce05098dc1d9c8eaac0595ba4',
|
||||
|
||||
'src/lib/tonic':
|
||||
Var('fuchsia_git') + '/tonic' + '@' + '5ca4053563027007ef2e7b2892efe63c26d30259',
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "flutter/glue/data_pipe_utils.h"
|
||||
#include "lib/ftl/files/eintr_wrapper.h"
|
||||
#include "lib/ftl/files/file.h"
|
||||
#include "lib/ftl/files/path.h"
|
||||
#include "lib/ftl/files/unique_fd.h"
|
||||
|
||||
@@ -22,13 +23,9 @@ void DirectoryAssetBundle::GetAsStream(
|
||||
mojo::DataPipe pipe;
|
||||
callback.Run(std::move(pipe.consumer_handle));
|
||||
|
||||
std::string asset_path =
|
||||
files::SimplifyPath(directory_ + "/" + asset_name.get());
|
||||
if (asset_path.find(directory_) != 0u) {
|
||||
FTL_LOG(ERROR) << "Asset name '" << asset_name
|
||||
<< "' attempted to traverse outside asset bundle.";
|
||||
std::string asset_path = GetPathForAsset(asset_name.get());
|
||||
if (asset_path.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(abarth): Consider moving the |open| call to task_runner_.
|
||||
ftl::UniqueFD fd(HANDLE_EINTR(open(asset_path.c_str(), O_RDONLY)));
|
||||
@@ -38,6 +35,14 @@ void DirectoryAssetBundle::GetAsStream(
|
||||
task_runner_, [](bool ignored) {});
|
||||
}
|
||||
|
||||
bool DirectoryAssetBundle::GetAsBuffer(const std::string& asset_name,
|
||||
std::vector<uint8_t>* data) {
|
||||
std::string asset_path = GetPathForAsset(asset_name);
|
||||
if (asset_path.empty())
|
||||
return false;
|
||||
return files::ReadFileToVector(asset_path, data);
|
||||
}
|
||||
|
||||
DirectoryAssetBundle::~DirectoryAssetBundle() {}
|
||||
|
||||
DirectoryAssetBundle::DirectoryAssetBundle(
|
||||
@@ -48,4 +53,15 @@ DirectoryAssetBundle::DirectoryAssetBundle(
|
||||
directory_(std::move(directory)),
|
||||
task_runner_(std::move(task_runner)) {}
|
||||
|
||||
std::string DirectoryAssetBundle::GetPathForAsset(
|
||||
const std::string& asset_name) {
|
||||
std::string asset_path = files::SimplifyPath(directory_ + "/" + asset_name);
|
||||
if (asset_path.find(directory_) != 0u) {
|
||||
FTL_LOG(ERROR) << "Asset name '" << asset_name
|
||||
<< "' attempted to traverse outside asset bundle.";
|
||||
return std::string();
|
||||
}
|
||||
return asset_path;
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
#include "lib/ftl/macros.h"
|
||||
#include "lib/ftl/tasks/task_runner.h"
|
||||
#include "mojo/public/cpp/bindings/binding.h"
|
||||
#include "mojo/public/cpp/bindings/interface_request.h"
|
||||
#include "mojo/public/cpp/bindings/strong_binding.h"
|
||||
#include "mojo/public/cpp/environment/async_waiter.h"
|
||||
#include "mojo/services/asset_bundle/interfaces/asset_bundle.mojom.h"
|
||||
|
||||
@@ -20,6 +20,7 @@ class DirectoryAssetBundle : public mojo::asset_bundle::AssetBundle {
|
||||
DirectoryAssetBundle(mojo::InterfaceRequest<AssetBundle> request,
|
||||
std::string directory,
|
||||
ftl::RefPtr<ftl::TaskRunner> task_runner);
|
||||
~DirectoryAssetBundle() override;
|
||||
|
||||
// mojo::assert_bundle::AssetBundle implementation:
|
||||
void GetAsStream(
|
||||
@@ -27,10 +28,12 @@ class DirectoryAssetBundle : public mojo::asset_bundle::AssetBundle {
|
||||
const mojo::Callback<void(mojo::ScopedDataPipeConsumerHandle)>& callback)
|
||||
override;
|
||||
|
||||
private:
|
||||
~DirectoryAssetBundle() override;
|
||||
bool GetAsBuffer(const std::string& asset_name, std::vector<uint8_t>* data);
|
||||
|
||||
mojo::StrongBinding<mojo::asset_bundle::AssetBundle> binding_;
|
||||
private:
|
||||
std::string GetPathForAsset(const std::string& asset_name);
|
||||
|
||||
mojo::Binding<mojo::asset_bundle::AssetBundle> binding_;
|
||||
const std::string directory_;
|
||||
ftl::RefPtr<ftl::TaskRunner> task_runner_;
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#define FLUTTER_ASSETS_ZIP_ASSET_BUNDLE_H_
|
||||
|
||||
#include "flutter/assets/zip_asset_store.h"
|
||||
#include "mojo/public/cpp/bindings/binding.h"
|
||||
#include "mojo/public/cpp/bindings/interface_request.h"
|
||||
#include "mojo/public/cpp/bindings/strong_binding.h"
|
||||
#include "mojo/services/asset_bundle/interfaces/asset_bundle.mojom.h"
|
||||
|
||||
namespace blink {
|
||||
@@ -17,6 +17,7 @@ class ZipAssetBundle : public mojo::asset_bundle::AssetBundle {
|
||||
ZipAssetBundle(
|
||||
mojo::InterfaceRequest<mojo::asset_bundle::AssetBundle> request,
|
||||
ftl::RefPtr<ZipAssetStore> store);
|
||||
~ZipAssetBundle() override;
|
||||
|
||||
// mojo::assert_bundle::AssetBundle implementation:
|
||||
void GetAsStream(
|
||||
@@ -25,9 +26,7 @@ class ZipAssetBundle : public mojo::asset_bundle::AssetBundle {
|
||||
override;
|
||||
|
||||
private:
|
||||
~ZipAssetBundle() override;
|
||||
|
||||
mojo::StrongBinding<mojo::asset_bundle::AssetBundle> binding_;
|
||||
mojo::Binding<mojo::asset_bundle::AssetBundle> binding_;
|
||||
ftl::RefPtr<ZipAssetStore> store_;
|
||||
};
|
||||
|
||||
|
||||
+31
-3
@@ -31,6 +31,8 @@
|
||||
namespace shell {
|
||||
namespace {
|
||||
|
||||
constexpr char kAssetPluginChannel[] = "flutter/assets";
|
||||
|
||||
bool PathExists(const std::string& path) {
|
||||
return access(path.c_str(), R_OK) == 0;
|
||||
}
|
||||
@@ -197,6 +199,9 @@ void Engine::RunFromSnapshotStream(
|
||||
void Engine::ConfigureAssetBundle(const std::string& path) {
|
||||
struct stat stat_result = {0};
|
||||
|
||||
directory_asset_bundle_.reset();
|
||||
zip_asset_bundle_.reset();
|
||||
|
||||
if (::stat(path.c_str(), &stat_result) != 0) {
|
||||
LOG(INFO) << "Could not configure asset bundle at path: " << path;
|
||||
return;
|
||||
@@ -204,8 +209,8 @@ void Engine::ConfigureAssetBundle(const std::string& path) {
|
||||
|
||||
if (S_ISDIR(stat_result.st_mode)) {
|
||||
// Directory asset bundle.
|
||||
new blink::DirectoryAssetBundle(mojo::GetProxy(&root_bundle_), path,
|
||||
blink::Threads::IO());
|
||||
directory_asset_bundle_ = std::make_unique<blink::DirectoryAssetBundle>(
|
||||
mojo::GetProxy(&root_bundle_), path, blink::Threads::IO());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -213,7 +218,8 @@ void Engine::ConfigureAssetBundle(const std::string& path) {
|
||||
// Zip asset bundle.
|
||||
asset_store_ = ftl::MakeRefCounted<blink::ZipAssetStore>(
|
||||
blink::GetUnzipperProviderForPath(path), blink::Threads::IO());
|
||||
new blink::ZipAssetBundle(mojo::GetProxy(&root_bundle_), asset_store_);
|
||||
zip_asset_bundle_ = std::make_unique<blink::ZipAssetBundle>(
|
||||
mojo::GetProxy(&root_bundle_), asset_store_);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -365,6 +371,10 @@ void Engine::UpdateSemantics(std::vector<blink::SemanticsNode> update) {
|
||||
|
||||
void Engine::HandlePlatformMessage(
|
||||
ftl::RefPtr<blink::PlatformMessage> message) {
|
||||
if (message->name() == kAssetPluginChannel) {
|
||||
HandleAssetPlatformMessage(std::move(message));
|
||||
return;
|
||||
}
|
||||
blink::Threads::Platform()->PostTask([
|
||||
platform_view = platform_view_, message = std::move(message)
|
||||
]() mutable {
|
||||
@@ -373,4 +383,22 @@ void Engine::HandlePlatformMessage(
|
||||
});
|
||||
}
|
||||
|
||||
void Engine::HandleAssetPlatformMessage(
|
||||
ftl::RefPtr<blink::PlatformMessage> message) {
|
||||
ftl::RefPtr<blink::PlatformMessageResponse> response = message->response();
|
||||
if (!response)
|
||||
return;
|
||||
const auto& data = message->data();
|
||||
std::string asset_name(reinterpret_cast<const char*>(data.data()),
|
||||
data.size());
|
||||
std::vector<uint8_t> asset_data;
|
||||
if ((directory_asset_bundle_ &&
|
||||
directory_asset_bundle_->GetAsBuffer(asset_name, &asset_data)) ||
|
||||
(asset_store_ && asset_store_->GetAsBuffer(asset_name, &asset_data))) {
|
||||
response->Complete(std::move(asset_data));
|
||||
} else {
|
||||
response->CompleteWithError();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace shell
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
#include "mojo/services/asset_bundle/interfaces/asset_bundle.mojom.h"
|
||||
#include "third_party/skia/include/core/SkPicture.h"
|
||||
|
||||
namespace blink {
|
||||
class DirectoryAssetBundle;
|
||||
class ZipAssetBundle;
|
||||
} // namespace blink
|
||||
|
||||
namespace shell {
|
||||
class PlatformView;
|
||||
class Animator;
|
||||
@@ -97,6 +102,8 @@ class Engine : public sky::SkyEngine, public blink::RuntimeDelegate {
|
||||
void ConfigureAssetBundle(const std::string& path);
|
||||
void ConfigureRuntime(const std::string& script_uri);
|
||||
|
||||
void HandleAssetPlatformMessage(ftl::RefPtr<blink::PlatformMessage> message);
|
||||
|
||||
ftl::WeakPtr<PlatformView> platform_view_;
|
||||
std::unique_ptr<Animator> animator_;
|
||||
|
||||
@@ -116,7 +123,10 @@ class Engine : public sky::SkyEngine, public blink::RuntimeDelegate {
|
||||
std::string country_code_;
|
||||
bool semantics_enabled_ = false;
|
||||
mojo::Binding<SkyEngine> binding_;
|
||||
|
||||
ftl::RefPtr<blink::ZipAssetStore> asset_store_;
|
||||
std::unique_ptr<blink::DirectoryAssetBundle> directory_asset_bundle_;
|
||||
std::unique_ptr<blink::ZipAssetBundle> zip_asset_bundle_;
|
||||
|
||||
// TODO(eseidel): This should move into an AnimatorStateMachine.
|
||||
bool activity_running_;
|
||||
|
||||
Reference in New Issue
Block a user