From d0c22cc8e51c5297d11f708be706ba1ce0582426 Mon Sep 17 00:00:00 2001 From: Yurii Zubrytskyi Date: Thu, 10 Nov 2022 14:11:05 -0800 Subject: [PATCH] IsFabricatedOverlay() optimization This function is used mostly to select what type should be parsing the very same file, so instead of opening that file again later make it able to accept an opened fd Bug: 237583012 Test: build + boot Change-Id: I9ca1f44d6fe16fec0dd4732bfc9f0d6272d3b1e7 --- libs/androidfw/ApkAssets.cpp | 9 ++++---- libs/androidfw/AssetsProvider.cpp | 4 ++-- libs/androidfw/ResourceTypes.cpp | 23 +++++++++++++++---- .../include/androidfw/AssetsProvider.h | 2 +- .../include/androidfw/ResourceTypes.h | 3 +++ 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp index 9aa37872b8de6..c0fa63a08fac6 100755 --- a/libs/androidfw/ApkAssets.cpp +++ b/libs/androidfw/ApkAssets.cpp @@ -83,15 +83,16 @@ std::unique_ptr ApkAssets::LoadOverlay(const std::string& idmap_path, return {}; } + std::string overlay_path(loaded_idmap->OverlayApkPath()); + auto fd = unique_fd(::open(overlay_path.c_str(), O_RDONLY|O_CLOEXEC)); std::unique_ptr overlay_assets; - const std::string overlay_path(loaded_idmap->OverlayApkPath()); - if (IsFabricatedOverlay(overlay_path)) { + if (IsFabricatedOverlay(fd)) { // Fabricated overlays do not contain resource definitions. All of the overlay resource values // are defined inline in the idmap. - overlay_assets = EmptyAssetsProvider::Create(overlay_path); + overlay_assets = EmptyAssetsProvider::Create(std::move(overlay_path)); } else { // The overlay should be an APK. - overlay_assets = ZipAssetsProvider::Create(overlay_path, flags); + overlay_assets = ZipAssetsProvider::Create(std::move(fd), std::move(overlay_path), flags); } if (overlay_assets == nullptr) { return {}; diff --git a/libs/androidfw/AssetsProvider.cpp b/libs/androidfw/AssetsProvider.cpp index 289d7e6604025..80e560747a3e3 100644 --- a/libs/androidfw/AssetsProvider.cpp +++ b/libs/androidfw/AssetsProvider.cpp @@ -393,8 +393,8 @@ std::unique_ptr EmptyAssetsProvider::Create() { return std::unique_ptr(new EmptyAssetsProvider({})); } -std::unique_ptr EmptyAssetsProvider::Create(const std::string& path) { - return std::unique_ptr(new EmptyAssetsProvider(path)); +std::unique_ptr EmptyAssetsProvider::Create(std::string path) { + return std::unique_ptr(new EmptyAssetsProvider(std::move(path))); } std::unique_ptr EmptyAssetsProvider::OpenInternal(const std::string& /* path */, diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 035ed4f394554..4a41ab521faa4 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -33,7 +33,9 @@ #include #include +#include #include +#include #include #include #include @@ -236,12 +238,23 @@ void Res_png_9patch::serialize(const Res_png_9patch& patch, const int32_t* xDivs } bool IsFabricatedOverlay(const std::string& path) { - std::ifstream fin(path); - uint32_t magic; - if (fin.read(reinterpret_cast(&magic), sizeof(uint32_t))) { - return magic == kFabricatedOverlayMagic; + return IsFabricatedOverlay(path.c_str()); +} + +bool IsFabricatedOverlay(const char* path) { + auto fd = base::unique_fd(base::utf8::open(path, O_RDONLY|O_CLOEXEC)); + if (fd < 0) { + return false; } - return false; + return IsFabricatedOverlay(fd); +} + +bool IsFabricatedOverlay(base::borrowed_fd fd) { + uint32_t magic; + if (!base::ReadFullyAtOffset(fd, &magic, sizeof(magic), 0)) { + return false; + } + return magic == kFabricatedOverlayMagic; } static bool assertIdmapHeader(const void* idmap, size_t size) { diff --git a/libs/androidfw/include/androidfw/AssetsProvider.h b/libs/androidfw/include/androidfw/AssetsProvider.h index 13cbe3bab84ca..af6e7f41e6bbc 100644 --- a/libs/androidfw/include/androidfw/AssetsProvider.h +++ b/libs/androidfw/include/androidfw/AssetsProvider.h @@ -181,7 +181,7 @@ struct MultiAssetsProvider : public AssetsProvider { // Does not provide any assets. struct EmptyAssetsProvider : public AssetsProvider { static std::unique_ptr Create(); - static std::unique_ptr Create(const std::string& path); + static std::unique_ptr Create(std::string path); bool ForEachFile(const std::string& path, const std::function& f) const override; diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h index d98e97ad32f08..6968977d7d12a 100644 --- a/libs/androidfw/include/androidfw/ResourceTypes.h +++ b/libs/androidfw/include/androidfw/ResourceTypes.h @@ -21,6 +21,7 @@ #define _LIBS_UTILS_RESOURCE_TYPES_H #include +#include #include #include @@ -58,6 +59,8 @@ constexpr const uint32_t kFabricatedOverlayCurrentVersion = 3; // Returns whether or not the path represents a fabricated overlay. bool IsFabricatedOverlay(const std::string& path); +bool IsFabricatedOverlay(const char* path); +bool IsFabricatedOverlay(android::base::borrowed_fd fd); /** * In C++11, char16_t is defined as *at least* 16 bits. We do a lot of