diff --git a/assets/BUILD.gn b/assets/BUILD.gn index c4901375ad810..28d7e569659f1 100644 --- a/assets/BUILD.gn +++ b/assets/BUILD.gn @@ -4,16 +4,18 @@ source_set("assets") { sources = [ - "asset_provider.h", + "asset_manager.cc", + "asset_manager.h", + "asset_resolver.h", "directory_asset_bundle.cc", "directory_asset_bundle.h", - "unzipper_provider.cc", - "unzipper_provider.h", "zip_asset_store.cc", "zip_asset_store.h", ] deps = [ + "$flutter_root/common", + "$flutter_root/fml", "$flutter_root/glue", "//garnet/public/lib/fxl", "//garnet/public/lib/zip", @@ -23,7 +25,5 @@ source_set("assets") { "//third_party/zlib:minizip", ] - public_configs = [ - "$flutter_root:config", - ] + public_configs = [ "$flutter_root:config" ] } diff --git a/assets/asset_manager.cc b/assets/asset_manager.cc new file mode 100644 index 0000000000000..8a313f0729c96 --- /dev/null +++ b/assets/asset_manager.cc @@ -0,0 +1,55 @@ +// Copyright 2017 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/assets/asset_manager.h" + +#include "flutter/assets/directory_asset_bundle.h" +#include "flutter/assets/zip_asset_store.h" +#include "flutter/glue/trace_event.h" +#include "lib/fxl/files/path.h" + +namespace blink { + +AssetManager::AssetManager() = default; + +AssetManager::~AssetManager() = default; + +void AssetManager::PushFront(std::unique_ptr resolver) { + if (resolver == nullptr || !resolver->IsValid()) { + return; + } + + resolvers_.push_front(std::move(resolver)); +} + +void AssetManager::PushBack(std::unique_ptr resolver) { + if (resolver == nullptr || !resolver->IsValid()) { + return; + } + + resolvers_.push_back(std::move(resolver)); +} + +// |blink::AssetResolver| +bool AssetManager::GetAsBuffer(const std::string& asset_name, + std::vector* data) const { + if (asset_name.size() == 0) { + return false; + } + TRACE_EVENT0("flutter", "AssetManager::GetAsBuffer"); + for (const auto& resolver : resolvers_) { + if (resolver->GetAsBuffer(asset_name, data)) { + return true; + } + } + FXL_DLOG(ERROR) << "Could not find asset: " << asset_name; + return false; +} + +// |blink::AssetResolver| +bool AssetManager::IsValid() const { + return resolvers_.size() > 0; +} + +} // namespace blink diff --git a/assets/asset_manager.h b/assets/asset_manager.h new file mode 100644 index 0000000000000..fc7f3ef05210e --- /dev/null +++ b/assets/asset_manager.h @@ -0,0 +1,47 @@ +// Copyright 2017 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_ASSETS_ASSET_MANAGER_H_ +#define FLUTTER_ASSETS_ASSET_MANAGER_H_ + +#include +#include +#include + +#include "flutter/assets/asset_resolver.h" +#include "lib/fxl/files/unique_fd.h" +#include "lib/fxl/macros.h" +#include "lib/fxl/memory/ref_counted.h" + +namespace blink { + +class AssetManager final : public AssetResolver, + public fxl::RefCountedThreadSafe { + public: + void PushFront(std::unique_ptr resolver); + + void PushBack(std::unique_ptr resolver); + + // |blink::AssetResolver| + bool IsValid() const override; + + // |blink::AssetResolver| + bool GetAsBuffer(const std::string& asset_name, + std::vector* data) const override; + + private: + std::deque> resolvers_; + + AssetManager(); + + ~AssetManager(); + + FXL_DISALLOW_COPY_AND_ASSIGN(AssetManager); + FRIEND_MAKE_REF_COUNTED(AssetManager); + FRIEND_REF_COUNTED_THREAD_SAFE(AssetManager); +}; + +} // namespace blink + +#endif // FLUTTER_ASSETS_ASSET_MANAGER_H_ diff --git a/assets/asset_provider.h b/assets/asset_provider.h deleted file mode 100644 index 68b7f5c2b7b9c..0000000000000 --- a/assets/asset_provider.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_ASSETS_ASSET_PROVIDER_H_ -#define FLUTTER_ASSETS_ASSET_PROVIDER_H_ - -#include -#include - -#include "lib/fxl/memory/ref_counted.h" - -namespace blink { - -class AssetProvider - : public fxl::RefCountedThreadSafe - { - public: - virtual bool GetAsBuffer(const std::string& asset_name, - std::vector* data) = 0; - virtual ~AssetProvider() = default; -}; - -} // namespace blink -#endif // FLUTTER_ASSETS_ASSET_PROVIDER_H diff --git a/assets/asset_resolver.h b/assets/asset_resolver.h new file mode 100644 index 0000000000000..6cfe27961a9f4 --- /dev/null +++ b/assets/asset_resolver.h @@ -0,0 +1,32 @@ +// Copyright 2017 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_ASSETS_ASSET_RESOLVER_H_ +#define FLUTTER_ASSETS_ASSET_RESOLVER_H_ + +#include +#include + +#include "lib/fxl/macros.h" + +namespace blink { + +class AssetResolver { + public: + AssetResolver() = default; + + virtual ~AssetResolver() = default; + + virtual bool IsValid() const = 0; + + virtual bool GetAsBuffer(const std::string& asset_name, + std::vector* data) const = 0; + + private: + FXL_DISALLOW_COPY_AND_ASSIGN(AssetResolver); +}; + +} // namespace blink + +#endif // FLUTTER_ASSETS_ASSET_RESOLVER_H_ diff --git a/assets/directory_asset_bundle.cc b/assets/directory_asset_bundle.cc index 43933079a81bd..a4ff6f832a936 100644 --- a/assets/directory_asset_bundle.cc +++ b/assets/directory_asset_bundle.cc @@ -3,73 +3,54 @@ // found in the LICENSE file. #include "flutter/assets/directory_asset_bundle.h" -#include "lib/fxl/build_config.h" - -#include #include +#include "flutter/fml/file.h" +#include "flutter/fml/mapping.h" #include "lib/fxl/files/eintr_wrapper.h" -#include "lib/fxl/files/file.h" -#include "lib/fxl/files/path.h" -#include "lib/fxl/files/unique_fd.h" -#include "lib/fxl/portable_unistd.h" namespace blink { -bool DirectoryAssetBundle::GetAsBuffer(const std::string& asset_name, - std::vector* data) { - if (fd_.is_valid()) { -#if defined(OS_WIN) - // This code path is not valid in a Windows environment. - return false; -#else - fxl::UniqueFD asset_file(openat(fd_.get(), asset_name.c_str(), O_RDONLY)); - if (!asset_file.is_valid()) - return false; - - constexpr size_t kBufferSize = 1 << 16; - size_t offset = 0; - ssize_t bytes_read = 0; - do { - offset += bytes_read; - data->resize(offset + kBufferSize); - bytes_read = read(asset_file.get(), &(*data)[offset], kBufferSize); - } while (bytes_read > 0); +DirectoryAssetBundle::DirectoryAssetBundle(fxl::UniqueFD descriptor) + : descriptor_(std::move(descriptor)) { + if (!fml::IsDirectory(descriptor_)) { + return; + } + is_valid_ = true; +} - if (bytes_read < 0) { - FXL_LOG(ERROR) << "Reading " << asset_name << " failed"; - data->clear(); - return false; - } +DirectoryAssetBundle::~DirectoryAssetBundle() = default; - data->resize(offset + bytes_read); - return true; -#endif - } - std::string asset_path = GetPathForAsset(asset_name); - if (asset_path.empty()) - return false; - return files::ReadFileToVector(asset_path, data); +// |blink::AssetResolver| +bool DirectoryAssetBundle::IsValid() const { + return is_valid_; } -DirectoryAssetBundle::~DirectoryAssetBundle() {} +// |blink::AssetResolver| +bool DirectoryAssetBundle::GetAsBuffer(const std::string& asset_name, + std::vector* data) const { + if (data == nullptr) { + return false; + } -DirectoryAssetBundle::DirectoryAssetBundle(std::string directory) - : directory_(std::move(directory)), fd_() {} + if (!is_valid_) { + FXL_DLOG(WARNING) << "Asset bundle was not valid."; + return false; + } -DirectoryAssetBundle::DirectoryAssetBundle(fxl::UniqueFD fd) - : fd_(std::move(fd)) {} + fml::FileMapping mapping( + fml::OpenFile(descriptor_, asset_name.c_str(), fml::OpenPermission::kRead, + false /* directory */), + false /* executable */); -std::string DirectoryAssetBundle::GetPathForAsset( - const std::string& asset_name) { - std::string asset_path = files::SimplifyPath(directory_ + "/" + asset_name); - if (asset_path.find(directory_) != 0u) { - FXL_LOG(ERROR) << "Asset name '" << asset_name - << "' attempted to traverse outside asset bundle."; - return std::string(); + if (mapping.GetMapping() == nullptr) { + return false; } - return asset_path; + + data->resize(mapping.GetSize()); + memmove(data->data(), mapping.GetMapping(), mapping.GetSize()); + return true; } } // namespace blink diff --git a/assets/directory_asset_bundle.h b/assets/directory_asset_bundle.h index c710a513796ae..d33a17b5f36b6 100644 --- a/assets/directory_asset_bundle.h +++ b/assets/directory_asset_bundle.h @@ -5,31 +5,31 @@ #ifndef FLUTTER_ASSETS_DIRECTORY_ASSET_BUNDLE_H_ #define FLUTTER_ASSETS_DIRECTORY_ASSET_BUNDLE_H_ -#include -#include - -#include "flutter/assets/asset_provider.h" +#include "flutter/assets/asset_resolver.h" #include "lib/fxl/files/unique_fd.h" #include "lib/fxl/macros.h" #include "lib/fxl/memory/ref_counted.h" namespace blink { -class DirectoryAssetBundle - : public AssetProvider { +class DirectoryAssetBundle : public AssetResolver { public: - explicit DirectoryAssetBundle(std::string directory); - // Expects fd to be valid, otherwise the file descriptor is ignored. - explicit DirectoryAssetBundle(fxl::UniqueFD fd); - virtual ~DirectoryAssetBundle(); - - virtual bool GetAsBuffer(const std::string& asset_name, std::vector* data); + explicit DirectoryAssetBundle(fxl::UniqueFD descriptor); - std::string GetPathForAsset(const std::string& asset_name); + ~DirectoryAssetBundle() override; private: - const std::string directory_; - fxl::UniqueFD fd_; + const fxl::UniqueFD descriptor_; + bool is_valid_ = false; + + std::string GetPathForAsset(const std::string& asset_name) const; + + // |blink::AssetResolver| + bool IsValid() const override; + + // |blink::AssetResolver| + bool GetAsBuffer(const std::string& asset_name, + std::vector* data) const override; FXL_DISALLOW_COPY_AND_ASSIGN(DirectoryAssetBundle); }; diff --git a/assets/file_asset_bundle.cc b/assets/file_asset_bundle.cc new file mode 100644 index 0000000000000..4ce25b172003c --- /dev/null +++ b/assets/file_asset_bundle.cc @@ -0,0 +1,27 @@ +// Copyright 2017 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/assets/file_asset_bundle.h" + +#include "lib/fxl/files/file.h" +#include "lib/fxl/files/path.h" + +namespace blink { + +FileAssetBundle::FileAssetBundle() = default; + +FileAssetBundle::~FileAssetBundle() = default; + +// |blink::AssetResolver| +bool FileAssetBundle::IsValid() const { + return true; +} + +// |blink::AssetResolver| +bool FileAssetBundle::GetAsBuffer(const std::string& asset_name, + std::vector* data) const { + return files::ReadFileToVector(files::AbsolutePath(asset_name), data); +} + +} // namespace blink diff --git a/assets/file_asset_bundle.h b/assets/file_asset_bundle.h new file mode 100644 index 0000000000000..36b9717525a37 --- /dev/null +++ b/assets/file_asset_bundle.h @@ -0,0 +1,32 @@ +// Copyright 2017 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_ASSETS_FILE_ASSET_BUNDLE_H_ +#define FLUTTER_ASSETS_FILE_ASSET_BUNDLE_H_ + +#include "flutter/assets/asset_resolver.h" +#include "lib/fxl/macros.h" + +namespace blink { + +class FileAssetBundle final : public AssetResolver { + public: + FileAssetBundle(); + + ~FileAssetBundle(); + + private: + // |blink::AssetResolver| + bool IsValid() const override; + + // |blink::AssetResolver| + bool GetAsBuffer(const std::string& asset_name, + std::vector* data) const override; + + FXL_DISALLOW_COPY_AND_ASSIGN(FileAssetBundle); +}; + +} // namespace blink + +#endif // FLUTTER_ASSETS_FILE_ASSET_BUNDLE_H_ diff --git a/assets/unzipper_provider.cc b/assets/unzipper_provider.cc deleted file mode 100644 index 8ed023f9a20e9..0000000000000 --- a/assets/unzipper_provider.cc +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/assets/unzipper_provider.h" - -#include "lib/fxl/logging.h" -#include "third_party/zlib/contrib/minizip/unzip.h" - -namespace blink { - -UnzipperProvider GetUnzipperProviderForPath(std::string zip_path) { - return [zip_path]() { - zip::UniqueUnzipper unzipper(unzOpen2(zip_path.c_str(), nullptr)); - if (!unzipper.is_valid()) - FXL_LOG(ERROR) << "Unable to open zip file: " << zip_path; - return unzipper; - }; -} - -} // namespace blink diff --git a/assets/unzipper_provider.h b/assets/unzipper_provider.h deleted file mode 100644 index f0f8d9597dffd..0000000000000 --- a/assets/unzipper_provider.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_ASSETS_UNZIP_PROVIDER_H_ -#define FLUTTER_ASSETS_UNZIP_PROVIDER_H_ - -#include - -#include "lib/zip/unique_unzipper.h" - -namespace blink { - -using UnzipperProvider = std::function; - -UnzipperProvider GetUnzipperProviderForPath(std::string zip_path); - -} // namespace blink - -#endif // FLUTTER_ASSETS_UNZIP_PROVIDER_H_ diff --git a/assets/zip_asset_store.cc b/assets/zip_asset_store.cc index c8534fa10c216..1b9216bd34530 100644 --- a/assets/zip_asset_store.cc +++ b/assets/zip_asset_store.cc @@ -15,21 +15,28 @@ #include #include "flutter/glue/trace_event.h" -#include "lib/fxl/files/eintr_wrapper.h" -#include "lib/fxl/files/unique_fd.h" -#include "lib/zip/unique_unzipper.h" namespace blink { -ZipAssetStore::ZipAssetStore(UnzipperProvider unzipper_provider) - : unzipper_provider_(std::move(unzipper_provider)) { +ZipAssetStore::ZipAssetStore(std::string file_path) + : file_path_(std::move(file_path)) { BuildStatCache(); } ZipAssetStore::~ZipAssetStore() = default; +zip::UniqueUnzipper ZipAssetStore::CreateUnzipper() const { + return zip::UniqueUnzipper{::unzOpen2(file_path_.c_str(), nullptr)}; +} + +// |blink::AssetResolver| +bool ZipAssetStore::IsValid() const { + return stat_cache_.size() > 0; +} + +// |blink::AssetResolver| bool ZipAssetStore::GetAsBuffer(const std::string& asset_name, - std::vector* data) { + std::vector* data) const { TRACE_EVENT0("flutter", "ZipAssetStore::GetAsBuffer"); auto found = stat_cache_.find(asset_name); @@ -37,7 +44,7 @@ bool ZipAssetStore::GetAsBuffer(const std::string& asset_name, return false; } - auto unzipper = unzipper_provider_(); + auto unzipper = CreateUnzipper(); if (!unzipper.is_valid()) { return false; @@ -73,7 +80,8 @@ bool ZipAssetStore::GetAsBuffer(const std::string& asset_name, void ZipAssetStore::BuildStatCache() { TRACE_EVENT0("flutter", "ZipAssetStore::BuildStatCache"); - auto unzipper = unzipper_provider_(); + + auto unzipper = CreateUnzipper(); if (!unzipper.is_valid()) { return; diff --git a/assets/zip_asset_store.h b/assets/zip_asset_store.h index 1ffda483ba9b7..558678e25bc08 100644 --- a/assets/zip_asset_store.h +++ b/assets/zip_asset_store.h @@ -6,21 +6,20 @@ #define FLUTTER_ASSETS_ZIP_ASSET_STORE_H_ #include -#include -#include "flutter/assets/unzipper_provider.h" +#include "flutter/assets/asset_resolver.h" #include "lib/fxl/macros.h" #include "lib/fxl/memory/ref_counted.h" +#include "lib/zip/unique_unzipper.h" #include "third_party/zlib/contrib/minizip/unzip.h" namespace blink { -class ZipAssetStore : public fxl::RefCountedThreadSafe { +class ZipAssetStore final : public AssetResolver { public: - explicit ZipAssetStore(UnzipperProvider unzipper_provider); - ~ZipAssetStore(); + ZipAssetStore(std::string file_path); - bool GetAsBuffer(const std::string& asset_name, std::vector* data); + ~ZipAssetStore() override; private: struct CacheEntry { @@ -30,11 +29,20 @@ class ZipAssetStore : public fxl::RefCountedThreadSafe { : file_pos(p_file_pos), uncompressed_size(p_uncompressed_size) {} }; - UnzipperProvider unzipper_provider_; - std::map stat_cache_; + std::string file_path_; + mutable std::map stat_cache_; + + // |blink::AssetResolver| + bool IsValid() const override; + + // |blink::AssetResolver| + bool GetAsBuffer(const std::string& asset_name, + std::vector* data) const override; void BuildStatCache(); + zip::UniqueUnzipper CreateUnzipper() const; + FXL_DISALLOW_COPY_AND_ASSIGN(ZipAssetStore); };