Loading libs/androidfw/ResourceTypes.cpp +66 −28 Original line number Diff line number Diff line Loading @@ -6557,6 +6557,44 @@ bool ResTable::getResourceFlags(uint32_t resID, uint32_t* outFlags) const { return true; } bool ResTable::getResourceEntryFlags(uint32_t resID, uint32_t* outFlags) 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 when getting flags for resource number 0x%08x", resID); } else { ALOGW("No known package when getting flags for resource number 0x%08x", resID); } return false; } if (t < 0) { ALOGW("No type identifier when getting flags for resource number 0x%08x", resID); return false; } const PackageGroup* const grp = mPackageGroups[p]; if (grp == NULL) { ALOGW("Bad identifier when getting flags 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; } *outFlags = entry.entry->flags(); return true; } bool ResTable::isPackageDynamic(uint8_t packageID) const { if (mError != NO_ERROR) { return false; Loading libs/androidfw/include/androidfw/ResourceTypes.h +5 −0 Original line number Diff line number Diff line Loading @@ -1593,6 +1593,8 @@ union ResTable_entry // If set, this is a compact entry with data type and value directly // encoded in the this entry, see ResTable_entry::compact FLAG_COMPACT = 0x0008, // If set, this entry relies on read write android feature flags FLAG_USES_FEATURE_FLAGS = 0x0010, }; struct Full { Loading Loading @@ -1622,6 +1624,7 @@ union ResTable_entry uint16_t flags() const { return dtohs(full.flags); }; bool is_compact() const { return flags() & FLAG_COMPACT; } bool is_complex() const { return flags() & FLAG_COMPLEX; } bool uses_feature_flags() const { return flags() & FLAG_USES_FEATURE_FLAGS; } size_t size() const { return is_compact() ? sizeof(ResTable_entry) : dtohs(this->full.size); Loading Loading @@ -2039,6 +2042,8 @@ public: bool getResourceFlags(uint32_t resID, uint32_t* outFlags) const; bool getResourceEntryFlags(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'. Loading tools/aapt2/Resource.h +2 −0 Original line number Diff line number Diff line Loading @@ -249,6 +249,8 @@ struct ResourceFile { // Flag std::optional<FeatureFlagAttribute> flag; bool uses_readwrite_feature_flags = false; }; /** Loading tools/aapt2/ResourceTable.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -664,6 +664,7 @@ bool ResourceTable::AddResource(NewResource&& res, android::IDiagnostics* diag) if (!config_value->value) { // Resource does not exist, add it now. config_value->value = std::move(res.value); config_value->uses_readwrite_feature_flags = res.uses_readwrite_feature_flags; } else { // When validation is enabled, ensure that a resource cannot have multiple values defined for // the same configuration unless protected by flags. Loading @@ -681,12 +682,14 @@ bool ResourceTable::AddResource(NewResource&& res, android::IDiagnostics* diag) ConfigKey{&res.config, res.product}, lt_config_key_ref()), util::make_unique<ResourceConfigValue>(res.config, res.product)); (*it)->value = std::move(res.value); (*it)->uses_readwrite_feature_flags = res.uses_readwrite_feature_flags; break; } case CollisionResult::kTakeNew: // Take the incoming value. config_value->value = std::move(res.value); config_value->uses_readwrite_feature_flags = res.uses_readwrite_feature_flags; break; case CollisionResult::kConflict: Loading Loading @@ -843,6 +846,12 @@ NewResourceBuilder& NewResourceBuilder::SetAllowMangled(bool allow_mangled) { return *this; } NewResourceBuilder& NewResourceBuilder::SetUsesReadWriteFeatureFlags( bool uses_readwrite_feature_flags) { res_.uses_readwrite_feature_flags = uses_readwrite_feature_flags; return *this; } NewResource NewResourceBuilder::Build() { return std::move(res_); } Loading tools/aapt2/ResourceTable.h +5 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,9 @@ class ResourceConfigValue { // The actual Value. std::unique_ptr<Value> value; // Whether the value uses read/write feature flags bool uses_readwrite_feature_flags = false; ResourceConfigValue(const android::ConfigDescription& config, android::StringPiece product) : config(config), product(product) { } Loading Loading @@ -284,6 +287,7 @@ struct NewResource { std::optional<AllowNew> allow_new; std::optional<StagedId> staged_id; bool allow_mangled = false; bool uses_readwrite_feature_flags = false; }; struct NewResourceBuilder { Loading @@ -297,6 +301,7 @@ struct NewResourceBuilder { NewResourceBuilder& SetAllowNew(AllowNew allow_new); NewResourceBuilder& SetStagedId(StagedId id); NewResourceBuilder& SetAllowMangled(bool allow_mangled); NewResourceBuilder& SetUsesReadWriteFeatureFlags(bool uses_feature_flags); NewResource Build(); private: Loading Loading
libs/androidfw/ResourceTypes.cpp +66 −28 Original line number Diff line number Diff line Loading @@ -6557,6 +6557,44 @@ bool ResTable::getResourceFlags(uint32_t resID, uint32_t* outFlags) const { return true; } bool ResTable::getResourceEntryFlags(uint32_t resID, uint32_t* outFlags) 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 when getting flags for resource number 0x%08x", resID); } else { ALOGW("No known package when getting flags for resource number 0x%08x", resID); } return false; } if (t < 0) { ALOGW("No type identifier when getting flags for resource number 0x%08x", resID); return false; } const PackageGroup* const grp = mPackageGroups[p]; if (grp == NULL) { ALOGW("Bad identifier when getting flags 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; } *outFlags = entry.entry->flags(); return true; } bool ResTable::isPackageDynamic(uint8_t packageID) const { if (mError != NO_ERROR) { return false; Loading
libs/androidfw/include/androidfw/ResourceTypes.h +5 −0 Original line number Diff line number Diff line Loading @@ -1593,6 +1593,8 @@ union ResTable_entry // If set, this is a compact entry with data type and value directly // encoded in the this entry, see ResTable_entry::compact FLAG_COMPACT = 0x0008, // If set, this entry relies on read write android feature flags FLAG_USES_FEATURE_FLAGS = 0x0010, }; struct Full { Loading Loading @@ -1622,6 +1624,7 @@ union ResTable_entry uint16_t flags() const { return dtohs(full.flags); }; bool is_compact() const { return flags() & FLAG_COMPACT; } bool is_complex() const { return flags() & FLAG_COMPLEX; } bool uses_feature_flags() const { return flags() & FLAG_USES_FEATURE_FLAGS; } size_t size() const { return is_compact() ? sizeof(ResTable_entry) : dtohs(this->full.size); Loading Loading @@ -2039,6 +2042,8 @@ public: bool getResourceFlags(uint32_t resID, uint32_t* outFlags) const; bool getResourceEntryFlags(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'. Loading
tools/aapt2/Resource.h +2 −0 Original line number Diff line number Diff line Loading @@ -249,6 +249,8 @@ struct ResourceFile { // Flag std::optional<FeatureFlagAttribute> flag; bool uses_readwrite_feature_flags = false; }; /** Loading
tools/aapt2/ResourceTable.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -664,6 +664,7 @@ bool ResourceTable::AddResource(NewResource&& res, android::IDiagnostics* diag) if (!config_value->value) { // Resource does not exist, add it now. config_value->value = std::move(res.value); config_value->uses_readwrite_feature_flags = res.uses_readwrite_feature_flags; } else { // When validation is enabled, ensure that a resource cannot have multiple values defined for // the same configuration unless protected by flags. Loading @@ -681,12 +682,14 @@ bool ResourceTable::AddResource(NewResource&& res, android::IDiagnostics* diag) ConfigKey{&res.config, res.product}, lt_config_key_ref()), util::make_unique<ResourceConfigValue>(res.config, res.product)); (*it)->value = std::move(res.value); (*it)->uses_readwrite_feature_flags = res.uses_readwrite_feature_flags; break; } case CollisionResult::kTakeNew: // Take the incoming value. config_value->value = std::move(res.value); config_value->uses_readwrite_feature_flags = res.uses_readwrite_feature_flags; break; case CollisionResult::kConflict: Loading Loading @@ -843,6 +846,12 @@ NewResourceBuilder& NewResourceBuilder::SetAllowMangled(bool allow_mangled) { return *this; } NewResourceBuilder& NewResourceBuilder::SetUsesReadWriteFeatureFlags( bool uses_readwrite_feature_flags) { res_.uses_readwrite_feature_flags = uses_readwrite_feature_flags; return *this; } NewResource NewResourceBuilder::Build() { return std::move(res_); } Loading
tools/aapt2/ResourceTable.h +5 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,9 @@ class ResourceConfigValue { // The actual Value. std::unique_ptr<Value> value; // Whether the value uses read/write feature flags bool uses_readwrite_feature_flags = false; ResourceConfigValue(const android::ConfigDescription& config, android::StringPiece product) : config(config), product(product) { } Loading Loading @@ -284,6 +287,7 @@ struct NewResource { std::optional<AllowNew> allow_new; std::optional<StagedId> staged_id; bool allow_mangled = false; bool uses_readwrite_feature_flags = false; }; struct NewResourceBuilder { Loading @@ -297,6 +301,7 @@ struct NewResourceBuilder { NewResourceBuilder& SetAllowNew(AllowNew allow_new); NewResourceBuilder& SetStagedId(StagedId id); NewResourceBuilder& SetAllowMangled(bool allow_mangled); NewResourceBuilder& SetUsesReadWriteFeatureFlags(bool uses_feature_flags); NewResource Build(); private: Loading