/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef APKASSETS_H_ #define APKASSETS_H_ #include #include #include "android-base/macros.h" #include "android-base/unique_fd.h" #include "androidfw/Asset.h" #include "androidfw/Idmap.h" #include "androidfw/LoadedArsc.h" #include "androidfw/misc.h" struct ZipArchive; typedef ZipArchive* ZipArchiveHandle; namespace android { class LoadedIdmap; // Interface for retrieving assets provided by an ApkAssets. class AssetsProvider { public: virtual ~AssetsProvider() = default; // Opens a file for reading. std::unique_ptr Open(const std::string& path, Asset::AccessMode mode = Asset::AccessMode::ACCESS_RANDOM, bool* file_exists = nullptr) const { return OpenInternal(path, mode, file_exists); } // Iterate over all files and directories provided by the zip. The order of iteration is stable. virtual bool ForEachFile(const std::string& /* path */, const std::function& /* f */) const { return true; } protected: AssetsProvider() = default; virtual std::unique_ptr OpenInternal(const std::string& path, Asset::AccessMode mode, bool* file_exists) const = 0; private: DISALLOW_COPY_AND_ASSIGN(AssetsProvider); }; class ZipAssetsProvider; // Holds an APK. class ApkAssets { public: // This means the data extends to the end of the file. static constexpr off64_t kUnknownLength = -1; // Creates an ApkAssets. // If `system` is true, the package is marked as a system package, and allows some functions to // filter out this package when computing what configurations/resources are available. static std::unique_ptr Load( const std::string& path, package_property_t flags = 0U, std::unique_ptr override_asset = nullptr); // Creates an ApkAssets from the given file descriptor, and takes ownership of the file // descriptor. The `friendly_name` is some name that will be used to identify the source of // this ApkAssets in log messages and other debug scenarios. // If `length` equals kUnknownLength, offset must equal 0; otherwise, the apk data will be read // using the `offset` into the file descriptor and will be `length` bytes long. static std::unique_ptr LoadFromFd( base::unique_fd fd, const std::string& friendly_name, package_property_t flags = 0U, std::unique_ptr override_asset = nullptr, off64_t offset = 0, off64_t length = kUnknownLength); // Creates an ApkAssets from the given path which points to a resources.arsc. static std::unique_ptr LoadTable( const std::string& path, package_property_t flags = 0U, std::unique_ptr override_asset = nullptr); // Creates an ApkAssets from the given file descriptor which points to an resources.arsc, and // takes ownership of the file descriptor. // If `length` equals kUnknownLength, offset must equal 0; otherwise, the .arsc data will be read // using the `offset` into the file descriptor and will be `length` bytes long. static std::unique_ptr LoadTableFromFd( base::unique_fd fd, const std::string& friendly_name, package_property_t flags = 0U, std::unique_ptr override_asset = nullptr, off64_t offset = 0, off64_t length = kUnknownLength); // Creates an ApkAssets from an IDMAP, which contains the original APK path, and the overlay // data. static std::unique_ptr LoadOverlay(const std::string& idmap_path, package_property_t flags = 0U); // Creates an ApkAssets from the directory path. File-based resources are read within the // directory as if the directory is an APK. static std::unique_ptr LoadFromDir( const std::string& path, package_property_t flags = 0U, std::unique_ptr override_asset = nullptr); // Creates a totally empty ApkAssets with no resources table and no file entries. static std::unique_ptr LoadEmpty( package_property_t flags = 0U, std::unique_ptr override_asset = nullptr); const std::string& GetPath() const { return path_; } const AssetsProvider* GetAssetsProvider() const { return assets_provider_.get(); } // This is never nullptr. const LoadedArsc* GetLoadedArsc() const { return loaded_arsc_.get(); } const LoadedIdmap* GetLoadedIdmap() const { return loaded_idmap_.get(); } bool IsLoader() const { return (property_flags_ & PROPERTY_LOADER) != 0; } bool IsOverlay() const { return loaded_idmap_ != nullptr; } // Returns whether the resources.arsc is allocated in RAM (not mmapped). bool IsTableAllocated() const { return resources_asset_ && resources_asset_->isAllocated(); } bool IsUpToDate() const; // Creates an Asset from a file on disk. static std::unique_ptr CreateAssetFromFile(const std::string& path); // Creates an Asset from a file descriptor. // // The asset takes ownership of the file descriptor. If `length` equals kUnknownLength, offset // must equal 0; otherwise, the asset data will be read using the `offset` into the file // descriptor and will be `length` bytes long. static std::unique_ptr CreateAssetFromFd(base::unique_fd fd, const char* path, off64_t offset = 0, off64_t length = kUnknownLength); private: DISALLOW_COPY_AND_ASSIGN(ApkAssets); static std::unique_ptr LoadImpl( std::unique_ptr assets, const std::string& path, package_property_t property_flags, std::unique_ptr override_assets = nullptr, std::unique_ptr idmap_asset = nullptr, std::unique_ptr idmap = nullptr); static std::unique_ptr LoadTableImpl( std::unique_ptr resources_asset, const std::string& path, package_property_t property_flags, std::unique_ptr override_assets = nullptr); ApkAssets(std::unique_ptr assets_provider, std::string path, time_t last_mod_time, package_property_t property_flags); std::unique_ptr assets_provider_; const std::string path_; time_t last_mod_time_; package_property_t property_flags_ = 0U; std::unique_ptr resources_asset_; std::unique_ptr idmap_asset_; std::unique_ptr loaded_arsc_; std::unique_ptr loaded_idmap_; }; } // namespace android #endif /* APKASSETS_H_ */