summaryrefslogtreecommitdiff
path: root/libs/androidfw/include
diff options
context:
space:
mode:
Diffstat (limited to 'libs/androidfw/include')
-rw-r--r--libs/androidfw/include/androidfw/ApkAssets.h56
-rw-r--r--libs/androidfw/include/androidfw/AssetManager.h33
-rw-r--r--libs/androidfw/include/androidfw/AssetManager2.h112
-rw-r--r--libs/androidfw/include/androidfw/Idmap.h76
-rw-r--r--libs/androidfw/include/androidfw/LoadedArsc.h89
-rw-r--r--libs/androidfw/include/androidfw/ResourceTypes.h50
-rw-r--r--libs/androidfw/include/androidfw/ResourceUtils.h4
-rw-r--r--libs/androidfw/include/androidfw/ZipFileRO.h6
8 files changed, 318 insertions, 108 deletions
diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h
index b7e66fb68be5..69702e314442 100644
--- a/libs/androidfw/include/androidfw/ApkAssets.h
+++ b/libs/androidfw/include/androidfw/ApkAssets.h
@@ -21,7 +21,7 @@
#include <string>
#include "android-base/macros.h"
-#include "ziparchive/zip_archive.h"
+#include "android-base/unique_fd.h"
#include "androidfw/Asset.h"
#include "androidfw/LoadedArsc.h"
@@ -29,41 +29,73 @@
namespace android {
+class LoadedIdmap;
+
// Holds an APK.
class ApkAssets {
public:
+ // 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<const ApkAssets> Load(const std::string& path, bool system = false);
+
+ // Creates an ApkAssets, but forces any package with ID 0x7f to be loaded as a shared library.
+ // 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<const ApkAssets> LoadAsSharedLibrary(const std::string& path,
bool system = false);
+ // Creates an ApkAssets from an IDMAP, which contains the original APK path, and the overlay
+ // data.
+ // 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<const ApkAssets> LoadOverlay(const std::string& idmap_path,
+ bool system = false);
+
+ // 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 `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.
+ // If `force_shared_lib` is true, any package with ID 0x7f is loaded as a shared library.
+ static std::unique_ptr<const ApkAssets> LoadFromFd(base::unique_fd fd,
+ const std::string& friendly_name, bool system,
+ bool force_shared_lib);
+
std::unique_ptr<Asset> Open(const std::string& path,
Asset::AccessMode mode = Asset::AccessMode::ACCESS_RANDOM) const;
bool ForEachFile(const std::string& path,
const std::function<void(const StringPiece&, FileType)>& f) const;
- inline const std::string& GetPath() const { return path_; }
+ inline const std::string& GetPath() const {
+ return path_;
+ }
- inline const LoadedArsc* GetLoadedArsc() const { return loaded_arsc_.get(); }
+ // This is never nullptr.
+ inline const LoadedArsc* GetLoadedArsc() const {
+ return loaded_arsc_.get();
+ }
private:
DISALLOW_COPY_AND_ASSIGN(ApkAssets);
- static std::unique_ptr<const ApkAssets> LoadImpl(const std::string& path, bool system,
- bool load_as_shared_library);
+ static std::unique_ptr<const ApkAssets> LoadImpl(base::unique_fd fd, const std::string& path,
+ std::unique_ptr<Asset> idmap_asset,
+ std::unique_ptr<const LoadedIdmap> loaded_idmap,
+ bool system, bool load_as_shared_library);
- ApkAssets() = default;
+ // Creates an Asset from any file on the file system.
+ static std::unique_ptr<Asset> CreateAssetFromFile(const std::string& path);
- struct ZipArchivePtrCloser {
- void operator()(::ZipArchiveHandle handle) { ::CloseArchive(handle); }
- };
+ ApkAssets(void* unmanaged_handle, const std::string& path);
- using ZipArchivePtr =
- std::unique_ptr<typename std::remove_pointer<::ZipArchiveHandle>::type, ZipArchivePtrCloser>;
+ using ZipArchivePtr = std::unique_ptr<void, void(*)(void*)>;
ZipArchivePtr zip_handle_;
- std::string path_;
+ const std::string path_;
std::unique_ptr<Asset> resources_asset_;
+ std::unique_ptr<Asset> idmap_asset_;
std::unique_ptr<const LoadedArsc> loaded_arsc_;
};
diff --git a/libs/androidfw/include/androidfw/AssetManager.h b/libs/androidfw/include/androidfw/AssetManager.h
index 0441b9d789e2..ecc5dc1ad331 100644
--- a/libs/androidfw/include/androidfw/AssetManager.h
+++ b/libs/androidfw/include/androidfw/AssetManager.h
@@ -92,6 +92,20 @@ public:
bool addOverlayPath(const String8& path, int32_t* cookie);
/*
+ * Add a new source for assets from an already open file descriptor.
+ * This does not give full AssetManager functionality for these assets,
+ * since the origin of the file is not known for purposes of sharing,
+ * overlay resolution, and other features. However it does allow you
+ * to do simple access to the contents of the given fd as an apk file.
+ *
+ * Returns "true" on success, "false" on failure. If 'cookie' is non-NULL,
+ * then on success, *cookie is set to the value corresponding to the
+ * newly-added asset source.
+ */
+ bool addAssetFd(int fd, const String8& debugPathName, int32_t* cookie,
+ bool appAsLib=false, bool assume_ownership=true);
+
+ /*
* Convenience for adding the standard system assets. Uses the
* ANDROID_ROOT environment variable to find them.
*/
@@ -195,24 +209,29 @@ public:
uint32_t targetCrc, uint32_t overlayCrc, uint32_t** outData, size_t* outSize);
private:
+ class SharedZip;
+
struct asset_path
{
- asset_path() : path(""), type(kFileTypeRegular), idmap(""),
- isSystemOverlay(false), isSystemAsset(false) {}
+ asset_path() : path(""), rawFd(-1), type(kFileTypeRegular), idmap(""),
+ isSystemOverlay(false), isSystemAsset(false), assumeOwnership(false) {}
String8 path;
+ int rawFd;
FileType type;
String8 idmap;
bool isSystemOverlay;
bool isSystemAsset;
+ bool assumeOwnership;
+ sp<SharedZip> zip;
};
Asset* openNonAssetInPathLocked(const char* fileName, AccessMode mode,
- const asset_path& path);
+ asset_path& path);
String8 createPathNameLocked(const asset_path& path, const char* rootDir);
String8 createZipSourceNameLocked(const String8& zipFileName,
const String8& dirName, const String8& fileName);
- ZipFileRO* getZipFileLocked(const asset_path& path);
+ ZipFileRO* getZipFileLocked(asset_path& path);
Asset* openAssetFromFileLocked(const String8& fileName, AccessMode mode);
Asset* openAssetFromZipLocked(const ZipFileRO* pZipFile,
const ZipEntryRO entry, AccessMode mode, const String8& entryName);
@@ -228,7 +247,7 @@ private:
const ResTable* getResTable(bool required = true) const;
void setLocaleLocked(const char* locale);
void updateResourceParamsLocked() const;
- bool appendPathToResTable(const asset_path& ap, bool appAsLib=false) const;
+ bool appendPathToResTable(asset_path& ap, bool appAsLib=false) const;
Asset* openIdmapLocked(const struct asset_path& ap) const;
@@ -238,6 +257,7 @@ private:
class SharedZip : public RefBase {
public:
static sp<SharedZip> get(const String8& path, bool createIfNotPresent = true);
+ static sp<SharedZip> create(int fd, const String8& path);
ZipFileRO* getZip();
@@ -257,6 +277,7 @@ private:
private:
SharedZip(const String8& path, time_t modWhen);
+ SharedZip(int fd, const String8& path);
SharedZip(); // <-- not implemented
String8 mPath;
@@ -290,6 +311,8 @@ private:
*/
ZipFileRO* getZip(const String8& path);
+ const sp<SharedZip> getSharedZip(const String8& path);
+
Asset* getZipResourceTableAsset(const String8& path);
Asset* setZipResourceTableAsset(const String8& path, Asset* asset);
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index d2bc6ee45576..b033137b4764 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -70,9 +70,8 @@ struct ResolvedBag {
};
// AssetManager2 is the main entry point for accessing assets and resources.
-// AssetManager2 provides caching of resources retrieved via the underlying
-// ApkAssets.
-class AssetManager2 : public ::AAssetManager {
+// AssetManager2 provides caching of resources retrieved via the underlying ApkAssets.
+class AssetManager2 {
public:
struct ResourceName {
const char* package = nullptr;
@@ -97,24 +96,29 @@ class AssetManager2 : public ::AAssetManager {
// new resource IDs.
bool SetApkAssets(const std::vector<const ApkAssets*>& apk_assets, bool invalidate_caches = true);
- inline const std::vector<const ApkAssets*> GetApkAssets() const { return apk_assets_; }
+ inline const std::vector<const ApkAssets*> GetApkAssets() const {
+ return apk_assets_;
+ }
// Returns the string pool for the given asset cookie.
- // Use the string pool returned here with a valid Res_value object of
- // type Res_value::TYPE_STRING.
+ // Use the string pool returned here with a valid Res_value object of type Res_value::TYPE_STRING.
const ResStringPool* GetStringPoolForCookie(ApkAssetsCookie cookie) const;
// Returns the DynamicRefTable for the given package ID.
+ // This may be nullptr if the APK represented by `cookie` has no resource table.
const DynamicRefTable* GetDynamicRefTableForPackage(uint32_t package_id) const;
// Returns the DynamicRefTable for the ApkAssets represented by the cookie.
+ // This may be nullptr if the APK represented by `cookie` has no resource table.
const DynamicRefTable* GetDynamicRefTableForCookie(ApkAssetsCookie cookie) const;
// Sets/resets the configuration for this AssetManager. This will cause all
// caches that are related to the configuration change to be invalidated.
void SetConfiguration(const ResTable_config& configuration);
- inline const ResTable_config& GetConfiguration() const { return configuration_; }
+ inline const ResTable_config& GetConfiguration() const {
+ return configuration_;
+ }
// Returns all configurations for which there are resources defined. This includes resource
// configurations in all the ApkAssets set for this AssetManager.
@@ -206,7 +210,7 @@ class AssetManager2 : public ::AAssetManager {
// are OR'd together with `in_out_flags`.
// `in_out_config` is populated with the configuration for which the resolved value was defined.
// `out_last_reference` is populated with the last reference ID before resolving to an actual
- // value.
+ // value. This is only initialized if the passed in `in_out_value` is a reference.
// Returns the cookie of the APK the resolved resource was defined in, or kInvalidCookie if
// it was not found.
ApkAssetsCookie ResolveReference(ApkAssetsCookie cookie, Res_value* in_out_value,
@@ -228,26 +232,35 @@ class AssetManager2 : public ::AAssetManager {
// Creates a new Theme from this AssetManager.
std::unique_ptr<Theme> NewTheme();
+ template <typename Func>
+ void ForEachPackage(Func func) {
+ for (const PackageGroup& package_group : package_groups_) {
+ func(package_group.packages_.front()->GetPackageName(),
+ package_group.dynamic_ref_table.mAssignedPackageId);
+ }
+ }
+
void DumpToLog() const;
private:
DISALLOW_COPY_AND_ASSIGN(AssetManager2);
- // Finds the best entry for `resid` amongst all the ApkAssets. The entry can be a simple
- // Res_value, or a complex map/bag type.
+ // Finds the best entry for `resid` from the set of ApkAssets. The entry can be a simple
+ // Res_value, or a complex map/bag type. If successful, it is available in `out_entry`.
+ // Returns kInvalidCookie on failure. Otherwise, the return value is the cookie associated with
+ // the ApkAssets in which the entry was found.
//
// `density_override` overrides the density of the current configuration when doing a search.
//
// When `stop_at_first_match` is true, the first match found is selected and the search
// terminates. This is useful for methods that just look up the name of a resource and don't
- // care about the value. In this case, the value of `out_flags` is incomplete and should not
- // be used.
+ // care about the value. In this case, the value of `FindEntryResult::type_flags` is incomplete
+ // and should not be used.
//
- // `out_flags` stores the resulting bitmask of configuration axis with which the resource
- // value varies.
+ // NOTE: FindEntry takes care of ensuring that structs within FindEntryResult have been properly
+ // bounds-checked. Callers of FindEntry are free to trust the data if this method succeeds.
ApkAssetsCookie FindEntry(uint32_t resid, uint16_t density_override, bool stop_at_first_match,
- LoadedArscEntry* out_entry, ResTable_config* out_selected_config,
- uint32_t* out_flags);
+ FindEntryResult* out_entry);
// Assigns package IDs to all shared library ApkAssets.
// Should be called whenever the ApkAssets are changed.
@@ -290,6 +303,8 @@ class Theme {
friend class AssetManager2;
public:
+ ~Theme();
+
// Applies the style identified by `resid` to this theme. This can be called
// multiple times with different styles. By default, any theme attributes that
// are already defined before this call are not overridden. If `force` is set
@@ -304,27 +319,31 @@ class Theme {
void Clear();
- inline const AssetManager2* GetAssetManager() const { return asset_manager_; }
+ inline const AssetManager2* GetAssetManager() const {
+ return asset_manager_;
+ }
- inline AssetManager2* GetAssetManager() { return asset_manager_; }
+ inline AssetManager2* GetAssetManager() {
+ return asset_manager_;
+ }
// Returns a bit mask of configuration changes that will impact this
// theme (and thus require completely reloading it).
- inline uint32_t GetChangingConfigurations() const { return type_spec_flags_; }
-
- // Retrieve a value in the theme. If the theme defines this value,
- // returns an asset cookie indicating which ApkAssets it came from
- // and populates `out_value` with the value. If `out_flags` is non-null,
- // populates it with a bitmask of the configuration axis the resource
- // varies with.
+ inline uint32_t GetChangingConfigurations() const {
+ return type_spec_flags_;
+ }
+
+ // Retrieve a value in the theme. If the theme defines this value, returns an asset cookie
+ // indicating which ApkAssets it came from and populates `out_value` with the value.
+ // `out_flags` is populated with a bitmask of the configuration axis with which the resource
+ // varies.
//
// If the attribute is not found, returns kInvalidCookie.
//
- // NOTE: This function does not do reference traversal. If you want
- // to follow references to other resources to get the "real" value to
- // use, you need to call ResolveReference() after this function.
- ApkAssetsCookie GetAttribute(uint32_t resid, Res_value* out_value,
- uint32_t* out_flags = nullptr) const;
+ // NOTE: This function does not do reference traversal. If you want to follow references to other
+ // resources to get the "real" value to use, you need to call ResolveReference() after this
+ // function.
+ ApkAssetsCookie GetAttribute(uint32_t resid, Res_value* out_value, uint32_t* out_flags) const;
// This is like AssetManager2::ResolveReference(), but also takes
// care of resolving attribute references to the theme.
@@ -337,36 +356,21 @@ class Theme {
DISALLOW_COPY_AND_ASSIGN(Theme);
// Called by AssetManager2.
- explicit inline Theme(AssetManager2* asset_manager) : asset_manager_(asset_manager) {}
-
- struct Entry {
- ApkAssetsCookie cookie;
- uint32_t type_spec_flags;
- Res_value value;
- };
-
- struct Type {
- // Use uint32_t for fewer cycles when loading from memory.
- uint32_t entry_count;
- uint32_t entry_capacity;
- Entry entries[0];
- };
-
- static constexpr const size_t kPackageCount = std::numeric_limits<uint8_t>::max() + 1;
- static constexpr const size_t kTypeCount = std::numeric_limits<uint8_t>::max() + 1;
-
- struct Package {
- // Each element of Type will be a dynamically sized object
- // allocated to have the entries stored contiguously with the Type.
- std::array<util::unique_cptr<Type>, kTypeCount> types;
- };
+ explicit Theme(AssetManager2* asset_manager);
AssetManager2* asset_manager_;
uint32_t type_spec_flags_ = 0u;
+
+ // Defined in the cpp.
+ struct Package;
+
+ constexpr static size_t kPackageCount = std::numeric_limits<uint8_t>::max() + 1;
std::array<std::unique_ptr<Package>, kPackageCount> packages_;
};
-inline const ResolvedBag::Entry* begin(const ResolvedBag* bag) { return bag->entries; }
+inline const ResolvedBag::Entry* begin(const ResolvedBag* bag) {
+ return bag->entries;
+}
inline const ResolvedBag::Entry* end(const ResolvedBag* bag) {
return bag->entries + bag->entry_count;
diff --git a/libs/androidfw/include/androidfw/Idmap.h b/libs/androidfw/include/androidfw/Idmap.h
new file mode 100644
index 000000000000..fd02e6f63b74
--- /dev/null
+++ b/libs/androidfw/include/androidfw/Idmap.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 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 IDMAP_H_
+#define IDMAP_H_
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "android-base/macros.h"
+
+#include "androidfw/StringPiece.h"
+
+namespace android {
+
+struct Idmap_header;
+struct IdmapEntry_header;
+
+// Represents a loaded/parsed IDMAP for a Runtime Resource Overlay (RRO).
+// An RRO and its target APK have different resource IDs assigned to their resources. Overlaying
+// a resource is done by resource name. An IDMAP is a generated mapping between the resource IDs
+// of the RRO and the target APK for each resource with the same name.
+// A LoadedIdmap can be set alongside the overlay's LoadedArsc to allow the overlay ApkAssets to
+// masquerade as the target ApkAssets resources.
+class LoadedIdmap {
+ public:
+ // Loads an IDMAP from a chunk of memory. Returns nullptr if the IDMAP data was malformed.
+ static std::unique_ptr<const LoadedIdmap> Load(const StringPiece& idmap_data);
+
+ // Performs a lookup of the expected entry ID for the given IDMAP entry header.
+ // Returns true if the mapping exists and fills `output_entry_id` with the result.
+ static bool Lookup(const IdmapEntry_header* header, uint16_t input_entry_id,
+ uint16_t* output_entry_id);
+
+ // Returns the package ID for which this overlay should apply.
+ uint8_t TargetPackageId() const;
+
+ // Returns the path to the RRO (Runtime Resource Overlay) APK for which this IDMAP was generated.
+ inline const std::string& OverlayApkPath() const {
+ return overlay_apk_path_;
+ }
+
+ // Returns the mapping of target entry ID to overlay entry ID for the given target type.
+ const IdmapEntry_header* GetEntryMapForType(uint8_t type_id) const;
+
+ protected:
+ // Exposed as protected so that tests can subclass and mock this class out.
+ LoadedIdmap() = default;
+
+ const Idmap_header* header_ = nullptr;
+ std::string overlay_apk_path_;
+ std::unordered_map<uint8_t, const IdmapEntry_header*> type_map_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LoadedIdmap);
+
+ explicit LoadedIdmap(const Idmap_header* header);
+};
+
+} // namespace android
+
+#endif // IDMAP_H_
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index f30b158084eb..965e2dbd2fb2 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -25,6 +25,7 @@
#include "androidfw/ByteBucketArray.h"
#include "androidfw/Chunk.h"
+#include "androidfw/Idmap.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/Util.h"
@@ -40,12 +41,18 @@ class DynamicPackageEntry {
int package_id = 0;
};
-struct LoadedArscEntry {
+struct FindEntryResult {
// A pointer to the resource table entry for this resource.
// If the size of the entry is > sizeof(ResTable_entry), it can be cast to
// a ResTable_map_entry and processed as a bag/map.
const ResTable_entry* entry = nullptr;
+ // The configuration for which the resulting entry was defined.
+ const ResTable_config* config = nullptr;
+
+ // Stores the resulting bitmask of configuration axis with which the resource value varies.
+ uint32_t type_flags = 0u;
+
// The dynamic package ID map for the package from which this resource came from.
const DynamicRefTable* dynamic_ref_table = nullptr;
@@ -62,28 +69,55 @@ struct TypeSpec;
class LoadedArsc;
class LoadedPackage {
- friend class LoadedArsc;
-
public:
+ static std::unique_ptr<const LoadedPackage> Load(const Chunk& chunk,
+ const LoadedIdmap* loaded_idmap, bool system,
+ bool load_as_shared_library);
+
+ ~LoadedPackage();
+
bool FindEntry(uint8_t type_idx, uint16_t entry_idx, const ResTable_config& config,
- LoadedArscEntry* out_entry, ResTable_config* out_selected_config,
- uint32_t* out_flags) const;
+ FindEntryResult* out_entry) const;
+
+ // Finds the entry with the specified type name and entry name. The names are in UTF-16 because
+ // the underlying ResStringPool API expects this. For now this is acceptable, but since
+ // the default policy in AAPT2 is to build UTF-8 string pools, this needs to change.
+ // Returns a partial resource ID, with the package ID left as 0x00. The caller is responsible
+ // for patching the correct package ID to the resource ID.
+ uint32_t FindEntryByName(const std::u16string& type_name, const std::u16string& entry_name) const;
// Returns the string pool where type names are stored.
- inline const ResStringPool* GetTypeStringPool() const { return &type_string_pool_; }
+ inline const ResStringPool* GetTypeStringPool() const {
+ return &type_string_pool_;
+ }
// Returns the string pool where the names of resource entries are stored.
- inline const ResStringPool* GetKeyStringPool() const { return &key_string_pool_; }
+ inline const ResStringPool* GetKeyStringPool() const {
+ return &key_string_pool_;
+ }
- inline const std::string& GetPackageName() const { return package_name_; }
+ inline const std::string& GetPackageName() const {
+ return package_name_;
+ }
- inline int GetPackageId() const { return package_id_; }
+ inline int GetPackageId() const {
+ return package_id_;
+ }
// Returns true if this package is dynamic (shared library) and needs to have an ID assigned.
- inline bool IsDynamic() const { return dynamic_; }
+ inline bool IsDynamic() const {
+ return dynamic_;
+ }
// Returns true if this package originates from a system provided resource.
- inline bool IsSystem() const { return system_; }
+ inline bool IsSystem() const {
+ return system_;
+ }
+
+ // Returns true if this package is from an overlay ApkAssets.
+ inline bool IsOverlay() const {
+ return overlay_;
+ }
// Returns the map of package name to package ID used in this LoadedPackage. At runtime, a
// package could have been assigned a different package ID than what this LoadedPackage was
@@ -101,19 +135,13 @@ class LoadedPackage {
// before being inserted into the set. This may cause some equivalent locales to de-dupe.
void CollectLocales(bool canonicalize, std::set<std::string>* out_locales) const;
- // Finds the entry with the specified type name and entry name. The names are in UTF-16 because
- // the underlying ResStringPool API expects this. For now this is acceptable, but since
- // the default policy in AAPT2 is to build UTF-8 string pools, this needs to change.
- // Returns a partial resource ID, with the package ID left as 0x00. The caller is responsible
- // for patching the correct package ID to the resource ID.
- uint32_t FindEntryByName(const std::u16string& type_name, const std::u16string& entry_name) const;
-
private:
DISALLOW_COPY_AND_ASSIGN(LoadedPackage);
- static std::unique_ptr<LoadedPackage> Load(const Chunk& chunk);
+ LoadedPackage();
- LoadedPackage() = default;
+ bool FindEntry(const util::unique_cptr<TypeSpec>& type_spec_ptr, uint16_t entry_idx,
+ const ResTable_config& config, FindEntryResult* out_entry) const;
ResStringPool type_string_pool_;
ResStringPool key_string_pool_;
@@ -122,6 +150,7 @@ class LoadedPackage {
int type_id_offset_ = 0;
bool dynamic_ = false;
bool system_ = false;
+ bool overlay_ = false;
ByteBucketArray<util::unique_cptr<TypeSpec>> type_specs_;
std::vector<DynamicPackageEntry> dynamic_package_map_;
@@ -137,27 +166,33 @@ class LoadedArsc {
// If `load_as_shared_library` is set to true, the application package (0x7f) is treated
// as a shared library (0x00). When loaded into an AssetManager, the package will be assigned an
// ID.
- static std::unique_ptr<const LoadedArsc> Load(const void* data, size_t len, bool system = false,
+ static std::unique_ptr<const LoadedArsc> Load(const StringPiece& data,
+ const LoadedIdmap* loaded_idmap = nullptr,
+ bool system = false,
bool load_as_shared_library = false);
- ~LoadedArsc();
+ // Create an empty LoadedArsc. This is used when an APK has no resources.arsc.
+ static std::unique_ptr<const LoadedArsc> CreateEmpty();
// Returns the string pool where all string resource values
// (Res_value::dataType == Res_value::TYPE_STRING) are indexed.
- inline const ResStringPool* GetStringPool() const { return &global_string_pool_; }
+ inline const ResStringPool* GetStringPool() const {
+ return &global_string_pool_;
+ }
// Finds the resource with ID `resid` with the best value for configuration `config`.
// The parameter `out_entry` will be filled with the resulting resource entry.
// The resource entry can be a simple entry (ResTable_entry) or a complex bag
// (ResTable_entry_map).
- bool FindEntry(uint32_t resid, const ResTable_config& config, LoadedArscEntry* out_entry,
- ResTable_config* selected_config, uint32_t* out_flags) const;
+ bool FindEntry(uint32_t resid, const ResTable_config& config, FindEntryResult* out_entry) const;
// Gets a pointer to the name of the package in `resid`, or nullptr if the package doesn't exist.
const LoadedPackage* GetPackageForId(uint32_t resid) const;
// Returns true if this is a system provided resource.
- inline bool IsSystem() const { return system_; }
+ inline bool IsSystem() const {
+ return system_;
+ }
// Returns a vector of LoadedPackage pointers, representing the packages in this LoadedArsc.
inline const std::vector<std::unique_ptr<const LoadedPackage>>& GetPackages() const {
@@ -168,7 +203,7 @@ class LoadedArsc {
DISALLOW_COPY_AND_ASSIGN(LoadedArsc);
LoadedArsc() = default;
- bool LoadTable(const Chunk& chunk, bool load_as_shared_library);
+ bool LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap, bool load_as_shared_library);
ResStringPool global_string_pool_;
std::vector<std::unique_ptr<const LoadedPackage>> packages_;
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 66c66c251d9b..20d017813cf7 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -38,6 +38,9 @@
namespace android {
+constexpr const static uint32_t kIdmapMagic = 0x504D4449u;
+constexpr const static uint32_t kIdmapCurrentVersion = 0x00000001u;
+
/**
* In C++11, char16_t is defined as *at least* 16 bits. We do a lot of
* casting on raw data and expect char16_t to be exactly 16 bits.
@@ -543,15 +546,15 @@ private:
*/
class StringPoolRef {
public:
- StringPoolRef();
- StringPoolRef(const ResStringPool* pool, uint32_t index);
+ StringPoolRef() = default;
+ StringPoolRef(const ResStringPool* pool, uint32_t index);
- const char* string8(size_t* outLen) const;
- const char16_t* string16(size_t* outLen) const;
+ const char* string8(size_t* outLen) const;
+ const char16_t* string16(size_t* outLen) const;
private:
- const ResStringPool* mPool;
- uint32_t mIndex;
+ const ResStringPool* mPool = nullptr;
+ uint32_t mIndex = 0u;
};
/** ********************************************************************
@@ -1179,6 +1182,10 @@ struct ResTable_config
// tried but could not compute a script.
bool localeScriptWasComputed;
+ // The value of BCP 47 Unicode extension for key 'nu' (numbering system).
+ // Varies in length from 3 to 8 chars. Zero-filled value.
+ char localeNumberingSystem[8];
+
void copyFromDeviceNoSwap(const ResTable_config& o);
void copyFromDtoH(const ResTable_config& o);
@@ -1256,9 +1263,9 @@ struct ResTable_config
// variants, it will be a modified bcp47 tag: b+en+Latn+US.
void appendDirLocale(String8& str) const;
- // Sets the values of language, region, script and variant to the
- // well formed BCP-47 locale contained in |in|. The input locale is
- // assumed to be valid and no validation is performed.
+ // Sets the values of language, region, script, variant and numbering
+ // system to the well formed BCP 47 locale contained in |in|.
+ // The input locale is assumed to be valid and no validation is performed.
void setBcp47Locale(const char* in);
inline void clearLocale() {
@@ -1266,6 +1273,7 @@ struct ResTable_config
localeScriptWasComputed = false;
memset(localeScript, 0, sizeof(localeScript));
memset(localeVariant, 0, sizeof(localeVariant));
+ memset(localeNumberingSystem, 0, sizeof(localeNumberingSystem));
}
inline void computeScript() {
@@ -1583,6 +1591,30 @@ struct ResTable_lib_entry
uint16_t packageName[128];
};
+struct alignas(uint32_t) Idmap_header {
+ // Always 0x504D4449 ('IDMP')
+ uint32_t magic;
+
+ uint32_t version;
+
+ uint32_t target_crc32;
+ uint32_t overlay_crc32;
+
+ uint8_t target_path[256];
+ uint8_t overlay_path[256];
+
+ uint16_t target_package_id;
+ uint16_t type_count;
+} __attribute__((packed));
+
+struct alignas(uint32_t) IdmapEntry_header {
+ uint16_t target_type_id;
+ uint16_t overlay_type_id;
+ uint16_t entry_count;
+ uint16_t entry_id_offset;
+ uint32_t entries[0];
+} __attribute__((packed));
+
class AssetManager2;
/**
diff --git a/libs/androidfw/include/androidfw/ResourceUtils.h b/libs/androidfw/include/androidfw/ResourceUtils.h
index 6bf7c2438797..c2eae855bb7b 100644
--- a/libs/androidfw/include/androidfw/ResourceUtils.h
+++ b/libs/androidfw/include/androidfw/ResourceUtils.h
@@ -40,7 +40,9 @@ inline uint8_t get_type_id(uint32_t resid) {
return static_cast<uint8_t>((resid >> 16) & 0x000000ffu);
}
-inline uint16_t get_entry_id(uint32_t resid) { return static_cast<uint16_t>(resid & 0x0000ffffu); }
+inline uint16_t get_entry_id(uint32_t resid) {
+ return static_cast<uint16_t>(resid & 0x0000ffffu);
+}
inline bool is_internal_resid(uint32_t resid) {
return (resid & 0xffff0000u) != 0 && (resid & 0x00ff0000u) == 0;
diff --git a/libs/androidfw/include/androidfw/ZipFileRO.h b/libs/androidfw/include/androidfw/ZipFileRO.h
index 768034287afa..03154d04def1 100644
--- a/libs/androidfw/include/androidfw/ZipFileRO.h
+++ b/libs/androidfw/include/androidfw/ZipFileRO.h
@@ -80,6 +80,12 @@ public:
static ZipFileRO* open(const char* zipFileName);
/*
+ * Open an archive from an already open file descriptor.
+ */
+ static ZipFileRO* openFd(int fd, const char* debugFileName,
+ bool assume_ownership = true);
+
+ /*
* Find an entry, by name. Returns the entry identifier, or NULL if
* not found.
*/