Loading libs/androidfw/ResourceTypes.cpp +74 −4 Original line number Diff line number Diff line Loading @@ -3504,13 +3504,14 @@ struct ResTable::PackageGroup { PackageGroup( ResTable* _owner, const String16& _name, uint32_t _id, bool appAsLib, bool _isSystemAsset) bool appAsLib, bool _isSystemAsset, bool _isDynamic) : owner(_owner) , name(_name) , id(_id) , largestTypeId(0) , dynamicRefTable(static_cast<uint8_t>(_id), appAsLib) , isSystemAsset(_isSystemAsset) , isDynamic(_isDynamic) { } ~PackageGroup() { Loading Loading @@ -3614,6 +3615,7 @@ struct ResTable::PackageGroup // If the package group comes from a system asset. Used in // determining non-system locales. const bool isSystemAsset; const bool isDynamic; }; ResTable::Theme::Theme(const ResTable& table) Loading Loading @@ -3982,6 +3984,11 @@ inline ssize_t ResTable::getResourcePackageIndex(uint32_t resID) const return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1; } inline ssize_t ResTable::getResourcePackageIndexFromPackage(uint8_t packageID) const { return ((ssize_t)mPackageMap[packageID])-1; } status_t ResTable::add(const void* data, size_t size, const int32_t cookie, bool copyData) { return addInternal(data, size, NULL, 0, false, cookie, copyData); } Loading Loading @@ -4037,7 +4044,7 @@ status_t ResTable::add(ResTable* src, bool isSystemAsset) for (size_t i=0; i < src->mPackageGroups.size(); i++) { PackageGroup* srcPg = src->mPackageGroups[i]; PackageGroup* pg = new PackageGroup(this, srcPg->name, srcPg->id, false /* appAsLib */, isSystemAsset || srcPg->isSystemAsset); false /* appAsLib */, isSystemAsset || srcPg->isSystemAsset, srcPg->isDynamic); for (size_t j=0; j<srcPg->packages.size(); j++) { pg->packages.add(srcPg->packages[j]); } Loading Loading @@ -6277,6 +6284,68 @@ bool ResTable::getResourceFlags(uint32_t resID, uint32_t* outFlags) const { return true; } bool ResTable::isPackageDynamic(uint8_t packageID) const { if (mError != NO_ERROR) { return false; } if (packageID == 0) { ALOGW("Invalid package number 0x%08x", packageID); return false; } const ssize_t p = getResourcePackageIndexFromPackage(packageID); if (p < 0) { ALOGW("Unknown package number 0x%08x", packageID); return false; } const PackageGroup* const grp = mPackageGroups[p]; if (grp == NULL) { ALOGW("Bad identifier for package number 0x%08x", packageID); return false; } return grp->isDynamic; } bool ResTable::isResourceDynamic(uint32_t resID) const { if (mError != NO_ERROR) { return false; } const ssize_t p = getResourcePackageIndex(resID); const int t = Res_GETTYPE(resID); const int e = Res_GETENTRY(resID); if (p < 0) { if (Res_GETPACKAGE(resID)+1 == 0) { ALOGW("No package identifier for resource number 0x%08x", resID); } else { ALOGW("No known package for resource number 0x%08x", resID); } return false; } if (t < 0) { ALOGW("No type identifier for resource number 0x%08x", resID); return false; } const PackageGroup* const grp = mPackageGroups[p]; if (grp == NULL) { ALOGW("Bad identifier for resource number 0x%08x", resID); return false; } Entry entry; status_t err = getEntry(grp, t, e, NULL, &entry); if (err != NO_ERROR) { return false; } return grp->isDynamic; } static bool keyCompare(const ResTable_sparseTypeEntry& entry , uint16_t entryIdx) { return dtohs(entry.idx) < entryIdx; } Loading Loading @@ -6520,12 +6589,14 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, id = targetPackageId; } bool isDynamic = false; if (id >= 256) { LOG_ALWAYS_FATAL("Package id out of range"); return NO_ERROR; } else if (id == 0 || (id == 0x7f && appAsLib) || isSystemAsset) { // This is a library or a system asset, so assign an ID id = mNextPackageId++; isDynamic = true; } PackageGroup* group = NULL; Loading Loading @@ -6553,10 +6624,9 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, size_t idx = mPackageMap[id]; if (idx == 0) { idx = mPackageGroups.size() + 1; char16_t tmpName[sizeof(pkg->name)/sizeof(pkg->name[0])]; strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(pkg->name[0])); group = new PackageGroup(this, String16(tmpName), id, appAsLib, isSystemAsset); group = new PackageGroup(this, String16(tmpName), id, appAsLib, isSystemAsset, isDynamic); if (group == NULL) { delete package; return (mError=NO_MEMORY); Loading libs/androidfw/include/androidfw/ResourceTypes.h +13 −0 Original line number Diff line number Diff line Loading @@ -1715,6 +1715,18 @@ public: bool getResourceFlags(uint32_t resID, uint32_t* outFlags) const; /** * Returns whether or not the package for the given resource has been dynamically assigned. * If the resource can't be found, returns 'false'. */ bool isResourceDynamic(uint32_t resID) const; /** * Returns whether or not the given package has been dynamically assigned. * If the package can't be found, returns 'false'. */ bool isPackageDynamic(uint8_t packageID) const; /** * Retrieve the value of a resource. If the resource is found, returns a * value >= 0 indicating the table it is in (for use with Loading Loading @@ -2024,6 +2036,7 @@ private: bool appAsLib, const int32_t cookie, bool copyData, bool isSystemAsset=false); ssize_t getResourcePackageIndex(uint32_t resID) const; ssize_t getResourcePackageIndexFromPackage(uint8_t packageID) const; status_t getEntry( const PackageGroup* packageGroup, int typeIndex, int entryIndex, Loading tools/aapt2/ResourceValues.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -117,8 +117,7 @@ bool Reference::Equals(const Value* value) const { bool Reference::Flatten(android::Res_value* out_value) const { const ResourceId resid = id.value_or_default(ResourceId(0)); const bool dynamic = resid.is_valid_dynamic() && resid.package_id() != kFrameworkPackageId && resid.package_id() < kAppPackageId; const bool dynamic = resid.is_valid_dynamic() && is_dynamic; if (reference_type == Reference::Type::kResource) { if (dynamic) { Loading tools/aapt2/ResourceValues.h +1 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ struct Reference : public BaseItem<Reference> { Maybe<ResourceId> id; Reference::Type reference_type; bool private_reference = false; bool is_dynamic = false; Reference(); explicit Reference(const ResourceNameRef& n, Type type = Type::kResource); Loading tools/aapt2/cmd/Link.cpp +25 −5 Original line number Diff line number Diff line Loading @@ -129,6 +129,12 @@ struct LinkOptions { // Stable ID options. std::unordered_map<ResourceName, ResourceId> stable_id_map; Maybe<std::string> resource_id_map_path; // When 'true', allow reserved package IDs to be used for applications. Pre-O, the platform // treats negative resource IDs [those with a package ID of 0x80 or higher] as invalid. // In order to work around this limitation, we allow the use of traditionally reserved // resource IDs [those between 0x02 and 0x7E]. bool allow_reserved_package_id = false; }; class LinkContext : public IAaptContext { Loading Loading @@ -899,9 +905,7 @@ class LinkCommand { // Capture the shared libraries so that the final resource table can be properly flattened // with support for shared libraries. for (auto& entry : asset_source->GetAssignedPackageIds()) { if (entry.first > kFrameworkPackageId && entry.first < kAppPackageId) { final_table_.included_packages_[entry.first] = entry.second; } else if (entry.first == kAppPackageId) { if (entry.first == kAppPackageId) { // Capture the included base feature package. included_feature_base_ = entry.second; } else if (entry.first == kFrameworkPackageId) { Loading @@ -915,6 +919,8 @@ class LinkCommand { // android:versionCode from the framework AndroidManifest.xml. ExtractCompileSdkVersions(asset_source->GetAssetManager()); } } else if (asset_source->IsPackageDynamic(entry.first)) { final_table_.included_packages_[entry.first] = entry.second; } } Loading Loading @@ -1599,7 +1605,15 @@ class LinkCommand { // If required, the package name is modifed before flattening, and then modified back // to its original name. ResourceTablePackage* package_to_rewrite = nullptr; if (context_->GetPackageId() > kAppPackageId && // Pre-O, the platform treats negative resource IDs [those with a package ID of 0x80 // or higher] as invalid. In order to work around this limitation, we allow the use // of traditionally reserved resource IDs [those between 0x02 and 0x7E]. Allow the // definition of what a valid "split" package ID is to account for this. const bool isSplitPackage = (options_.allow_reserved_package_id && context_->GetPackageId() != kAppPackageId && context_->GetPackageId() != kFrameworkPackageId) || (!options_.allow_reserved_package_id && context_->GetPackageId() > kAppPackageId); if (isSplitPackage && included_feature_base_ == make_value(context_->GetCompilationPackage())) { // The base APK is included, and this is a feature split. If the base package is // the same as this package, then we are building an old style Android Instant Apps feature Loading Loading @@ -2150,6 +2164,10 @@ int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics) { "Generates a text file containing the resource symbols of the R class in\n" "the specified folder.", &options.generate_text_symbols_path) .OptionalSwitch("--allow-reserved-package-id", "Allows the use of a reserved package ID. This should on be used for\n" "packages with a pre-O min-sdk\n", &options.allow_reserved_package_id) .OptionalSwitch("--auto-add-overlay", "Allows the addition of new resources in overlays without\n" "<add-resource> tags.", Loading Loading @@ -2249,7 +2267,9 @@ int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics) { } const uint32_t package_id_int = maybe_package_id_int.value(); if (package_id_int < kAppPackageId || package_id_int > std::numeric_limits<uint8_t>::max()) { if (package_id_int > std::numeric_limits<uint8_t>::max() || package_id_int == kFrameworkPackageId || (!options.allow_reserved_package_id && package_id_int < kAppPackageId)) { context.GetDiagnostics()->Error( DiagMessage() << StringPrintf( "invalid package ID 0x%02x. Must be in the range 0x7f-0xff.", package_id_int)); Loading Loading
libs/androidfw/ResourceTypes.cpp +74 −4 Original line number Diff line number Diff line Loading @@ -3504,13 +3504,14 @@ struct ResTable::PackageGroup { PackageGroup( ResTable* _owner, const String16& _name, uint32_t _id, bool appAsLib, bool _isSystemAsset) bool appAsLib, bool _isSystemAsset, bool _isDynamic) : owner(_owner) , name(_name) , id(_id) , largestTypeId(0) , dynamicRefTable(static_cast<uint8_t>(_id), appAsLib) , isSystemAsset(_isSystemAsset) , isDynamic(_isDynamic) { } ~PackageGroup() { Loading Loading @@ -3614,6 +3615,7 @@ struct ResTable::PackageGroup // If the package group comes from a system asset. Used in // determining non-system locales. const bool isSystemAsset; const bool isDynamic; }; ResTable::Theme::Theme(const ResTable& table) Loading Loading @@ -3982,6 +3984,11 @@ inline ssize_t ResTable::getResourcePackageIndex(uint32_t resID) const return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1; } inline ssize_t ResTable::getResourcePackageIndexFromPackage(uint8_t packageID) const { return ((ssize_t)mPackageMap[packageID])-1; } status_t ResTable::add(const void* data, size_t size, const int32_t cookie, bool copyData) { return addInternal(data, size, NULL, 0, false, cookie, copyData); } Loading Loading @@ -4037,7 +4044,7 @@ status_t ResTable::add(ResTable* src, bool isSystemAsset) for (size_t i=0; i < src->mPackageGroups.size(); i++) { PackageGroup* srcPg = src->mPackageGroups[i]; PackageGroup* pg = new PackageGroup(this, srcPg->name, srcPg->id, false /* appAsLib */, isSystemAsset || srcPg->isSystemAsset); false /* appAsLib */, isSystemAsset || srcPg->isSystemAsset, srcPg->isDynamic); for (size_t j=0; j<srcPg->packages.size(); j++) { pg->packages.add(srcPg->packages[j]); } Loading Loading @@ -6277,6 +6284,68 @@ bool ResTable::getResourceFlags(uint32_t resID, uint32_t* outFlags) const { return true; } bool ResTable::isPackageDynamic(uint8_t packageID) const { if (mError != NO_ERROR) { return false; } if (packageID == 0) { ALOGW("Invalid package number 0x%08x", packageID); return false; } const ssize_t p = getResourcePackageIndexFromPackage(packageID); if (p < 0) { ALOGW("Unknown package number 0x%08x", packageID); return false; } const PackageGroup* const grp = mPackageGroups[p]; if (grp == NULL) { ALOGW("Bad identifier for package number 0x%08x", packageID); return false; } return grp->isDynamic; } bool ResTable::isResourceDynamic(uint32_t resID) const { if (mError != NO_ERROR) { return false; } const ssize_t p = getResourcePackageIndex(resID); const int t = Res_GETTYPE(resID); const int e = Res_GETENTRY(resID); if (p < 0) { if (Res_GETPACKAGE(resID)+1 == 0) { ALOGW("No package identifier for resource number 0x%08x", resID); } else { ALOGW("No known package for resource number 0x%08x", resID); } return false; } if (t < 0) { ALOGW("No type identifier for resource number 0x%08x", resID); return false; } const PackageGroup* const grp = mPackageGroups[p]; if (grp == NULL) { ALOGW("Bad identifier for resource number 0x%08x", resID); return false; } Entry entry; status_t err = getEntry(grp, t, e, NULL, &entry); if (err != NO_ERROR) { return false; } return grp->isDynamic; } static bool keyCompare(const ResTable_sparseTypeEntry& entry , uint16_t entryIdx) { return dtohs(entry.idx) < entryIdx; } Loading Loading @@ -6520,12 +6589,14 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, id = targetPackageId; } bool isDynamic = false; if (id >= 256) { LOG_ALWAYS_FATAL("Package id out of range"); return NO_ERROR; } else if (id == 0 || (id == 0x7f && appAsLib) || isSystemAsset) { // This is a library or a system asset, so assign an ID id = mNextPackageId++; isDynamic = true; } PackageGroup* group = NULL; Loading Loading @@ -6553,10 +6624,9 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, size_t idx = mPackageMap[id]; if (idx == 0) { idx = mPackageGroups.size() + 1; char16_t tmpName[sizeof(pkg->name)/sizeof(pkg->name[0])]; strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(pkg->name[0])); group = new PackageGroup(this, String16(tmpName), id, appAsLib, isSystemAsset); group = new PackageGroup(this, String16(tmpName), id, appAsLib, isSystemAsset, isDynamic); if (group == NULL) { delete package; return (mError=NO_MEMORY); Loading
libs/androidfw/include/androidfw/ResourceTypes.h +13 −0 Original line number Diff line number Diff line Loading @@ -1715,6 +1715,18 @@ public: bool getResourceFlags(uint32_t resID, uint32_t* outFlags) const; /** * Returns whether or not the package for the given resource has been dynamically assigned. * If the resource can't be found, returns 'false'. */ bool isResourceDynamic(uint32_t resID) const; /** * Returns whether or not the given package has been dynamically assigned. * If the package can't be found, returns 'false'. */ bool isPackageDynamic(uint8_t packageID) const; /** * Retrieve the value of a resource. If the resource is found, returns a * value >= 0 indicating the table it is in (for use with Loading Loading @@ -2024,6 +2036,7 @@ private: bool appAsLib, const int32_t cookie, bool copyData, bool isSystemAsset=false); ssize_t getResourcePackageIndex(uint32_t resID) const; ssize_t getResourcePackageIndexFromPackage(uint8_t packageID) const; status_t getEntry( const PackageGroup* packageGroup, int typeIndex, int entryIndex, Loading
tools/aapt2/ResourceValues.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -117,8 +117,7 @@ bool Reference::Equals(const Value* value) const { bool Reference::Flatten(android::Res_value* out_value) const { const ResourceId resid = id.value_or_default(ResourceId(0)); const bool dynamic = resid.is_valid_dynamic() && resid.package_id() != kFrameworkPackageId && resid.package_id() < kAppPackageId; const bool dynamic = resid.is_valid_dynamic() && is_dynamic; if (reference_type == Reference::Type::kResource) { if (dynamic) { Loading
tools/aapt2/ResourceValues.h +1 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ struct Reference : public BaseItem<Reference> { Maybe<ResourceId> id; Reference::Type reference_type; bool private_reference = false; bool is_dynamic = false; Reference(); explicit Reference(const ResourceNameRef& n, Type type = Type::kResource); Loading
tools/aapt2/cmd/Link.cpp +25 −5 Original line number Diff line number Diff line Loading @@ -129,6 +129,12 @@ struct LinkOptions { // Stable ID options. std::unordered_map<ResourceName, ResourceId> stable_id_map; Maybe<std::string> resource_id_map_path; // When 'true', allow reserved package IDs to be used for applications. Pre-O, the platform // treats negative resource IDs [those with a package ID of 0x80 or higher] as invalid. // In order to work around this limitation, we allow the use of traditionally reserved // resource IDs [those between 0x02 and 0x7E]. bool allow_reserved_package_id = false; }; class LinkContext : public IAaptContext { Loading Loading @@ -899,9 +905,7 @@ class LinkCommand { // Capture the shared libraries so that the final resource table can be properly flattened // with support for shared libraries. for (auto& entry : asset_source->GetAssignedPackageIds()) { if (entry.first > kFrameworkPackageId && entry.first < kAppPackageId) { final_table_.included_packages_[entry.first] = entry.second; } else if (entry.first == kAppPackageId) { if (entry.first == kAppPackageId) { // Capture the included base feature package. included_feature_base_ = entry.second; } else if (entry.first == kFrameworkPackageId) { Loading @@ -915,6 +919,8 @@ class LinkCommand { // android:versionCode from the framework AndroidManifest.xml. ExtractCompileSdkVersions(asset_source->GetAssetManager()); } } else if (asset_source->IsPackageDynamic(entry.first)) { final_table_.included_packages_[entry.first] = entry.second; } } Loading Loading @@ -1599,7 +1605,15 @@ class LinkCommand { // If required, the package name is modifed before flattening, and then modified back // to its original name. ResourceTablePackage* package_to_rewrite = nullptr; if (context_->GetPackageId() > kAppPackageId && // Pre-O, the platform treats negative resource IDs [those with a package ID of 0x80 // or higher] as invalid. In order to work around this limitation, we allow the use // of traditionally reserved resource IDs [those between 0x02 and 0x7E]. Allow the // definition of what a valid "split" package ID is to account for this. const bool isSplitPackage = (options_.allow_reserved_package_id && context_->GetPackageId() != kAppPackageId && context_->GetPackageId() != kFrameworkPackageId) || (!options_.allow_reserved_package_id && context_->GetPackageId() > kAppPackageId); if (isSplitPackage && included_feature_base_ == make_value(context_->GetCompilationPackage())) { // The base APK is included, and this is a feature split. If the base package is // the same as this package, then we are building an old style Android Instant Apps feature Loading Loading @@ -2150,6 +2164,10 @@ int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics) { "Generates a text file containing the resource symbols of the R class in\n" "the specified folder.", &options.generate_text_symbols_path) .OptionalSwitch("--allow-reserved-package-id", "Allows the use of a reserved package ID. This should on be used for\n" "packages with a pre-O min-sdk\n", &options.allow_reserved_package_id) .OptionalSwitch("--auto-add-overlay", "Allows the addition of new resources in overlays without\n" "<add-resource> tags.", Loading Loading @@ -2249,7 +2267,9 @@ int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics) { } const uint32_t package_id_int = maybe_package_id_int.value(); if (package_id_int < kAppPackageId || package_id_int > std::numeric_limits<uint8_t>::max()) { if (package_id_int > std::numeric_limits<uint8_t>::max() || package_id_int == kFrameworkPackageId || (!options.allow_reserved_package_id && package_id_int < kAppPackageId)) { context.GetDiagnostics()->Error( DiagMessage() << StringPrintf( "invalid package ID 0x%02x. Must be in the range 0x7f-0xff.", package_id_int)); Loading