Loading libs/androidfw/include/androidfw/ResourceTypes.h +4 −0 Original line number Diff line number Diff line Loading @@ -1647,6 +1647,10 @@ struct ResTable_overlayable_policy_header // The overlay must reside of the product partition or must have existed on the product // partition before an upgrade to overlay these resources. POLICY_PRODUCT_PARTITION = 0x00000008, // The overlay must be signed with the same signature as the actor of the target resource, // which can be separate or the same as the target package with the resource. POLICY_SIGNATURE = 0x00000010, }; uint32_t policy_flags; Loading tools/aapt2/ResourceParser.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -1113,6 +1113,13 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource const std::string& element_name = parser->element_name(); const std::string& element_namespace = parser->element_namespace(); if (element_namespace.empty() && element_name == "item") { if (current_policies == OverlayableItem::Policy::kNone) { diag_->Error(DiagMessage(element_source) << "<item> within an <overlayable> must be inside a <policy> block"); error = true; continue; } // Items specify the name and type of resource that should be overlayable Maybe<StringPiece> item_name = xml::FindNonEmptyAttribute(parser, "name"); if (!item_name) { Loading Loading @@ -1169,6 +1176,8 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource current_policies |= OverlayableItem::Policy::kSystem; } else if (trimmed_part == "vendor") { current_policies |= OverlayableItem::Policy::kVendor; } else if (trimmed_part == "signature") { current_policies |= OverlayableItem::Policy::kSignature; } else { diag_->Error(DiagMessage(element_source) << "<policy> has unsupported type '" << trimmed_part << "'"); Loading @@ -1176,6 +1185,11 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource continue; } } } else { diag_->Error(DiagMessage(element_source) << "<policy> must have a 'type' attribute"); error = true; continue; } } else if (!ShouldIgnoreElement(element_namespace, element_name)) { diag_->Error(DiagMessage(element_source) << "invalid element <" << element_name << "> " Loading tools/aapt2/ResourceParser_test.cpp +34 −14 Original line number Diff line number Diff line Loading @@ -894,8 +894,10 @@ TEST_F(ResourceParserTest, ParsePlatformIndependentNewline) { TEST_F(ResourceParserTest, ParseOverlayable) { std::string input = R"( <overlayable name="Name" actor="overlay://theme"> <policy type="signature"> <item type="string" name="foo" /> <item type="drawable" name="bar" /> </policy> </overlayable>)"; ASSERT_TRUE(TestParse(input)); Loading @@ -906,7 +908,7 @@ TEST_F(ResourceParserTest, ParseOverlayable) { OverlayableItem& result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); EXPECT_THAT(result_overlayable_item.overlayable->actor, Eq("overlay://theme")); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kNone)); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kSignature)); search_result = table_.FindResource(test::ParseNameOrDie("drawable/bar")); ASSERT_TRUE(search_result); Loading @@ -915,7 +917,7 @@ TEST_F(ResourceParserTest, ParseOverlayable) { result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); EXPECT_THAT(result_overlayable_item.overlayable->actor, Eq("overlay://theme")); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kNone)); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kSignature)); } TEST_F(ResourceParserTest, ParseOverlayableRequiresName) { Loading @@ -931,7 +933,6 @@ TEST_F(ResourceParserTest, ParseOverlayableBadActorFail) { TEST_F(ResourceParserTest, ParseOverlayablePolicy) { std::string input = R"( <overlayable name="Name"> <item type="string" name="foo" /> <policy type="product"> <item type="string" name="bar" /> </policy> Loading @@ -944,23 +945,18 @@ TEST_F(ResourceParserTest, ParseOverlayablePolicy) { <policy type="public"> <item type="string" name="faz" /> </policy> <policy type="signature"> <item type="string" name="foz" /> </policy> </overlayable>)"; ASSERT_TRUE(TestParse(input)); auto search_result = table_.FindResource(test::ParseNameOrDie("string/foo")); auto search_result = table_.FindResource(test::ParseNameOrDie("string/bar")); ASSERT_TRUE(search_result); ASSERT_THAT(search_result.value().entry, NotNull()); ASSERT_TRUE(search_result.value().entry->overlayable_item); OverlayableItem result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kNone)); search_result = table_.FindResource(test::ParseNameOrDie("string/bar")); ASSERT_TRUE(search_result); ASSERT_THAT(search_result.value().entry, NotNull()); ASSERT_TRUE(search_result.value().entry->overlayable_item); result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kProduct)); search_result = table_.FindResource(test::ParseNameOrDie("string/fiz")); Loading @@ -986,6 +982,30 @@ TEST_F(ResourceParserTest, ParseOverlayablePolicy) { result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kPublic)); search_result = table_.FindResource(test::ParseNameOrDie("string/foz")); ASSERT_TRUE(search_result); ASSERT_THAT(search_result.value().entry, NotNull()); ASSERT_TRUE(search_result.value().entry->overlayable_item); result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kSignature)); } TEST_F(ResourceParserTest, ParseOverlayableNoPolicyError) { std::string input = R"( <overlayable name="Name"> <item type="string" name="foo" /> </overlayable>)"; EXPECT_FALSE(TestParse(input)); input = R"( <overlayable name="Name"> <policy> <item name="foo" /> </policy> </overlayable>)"; EXPECT_FALSE(TestParse(input)); } TEST_F(ResourceParserTest, ParseOverlayableBadPolicyError) { Loading tools/aapt2/ResourceTable.h +3 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,9 @@ struct OverlayableItem { // The resource can be overlaid by any overlay on the product partition. kProduct = 0x08, // The resource can be overlaid by any overlay signed with the same signature as its actor. kSignature = 0x010, }; std::shared_ptr<Overlayable> overlayable; Loading tools/aapt2/Resources.proto +2 −2 Original line number Diff line number Diff line Loading @@ -138,10 +138,10 @@ message AllowNew { // Represents a set of overlayable resources. message Overlayable { // The name of the <overlyabale>. // The name of the <overlayable>. string name = 1; // The location of the <overlyabale> declaration in the source. // The location of the <overlayable> declaration in the source. Source source = 2; // The component responsible for enabling and disabling overlays targeting this <overlayable>. Loading Loading
libs/androidfw/include/androidfw/ResourceTypes.h +4 −0 Original line number Diff line number Diff line Loading @@ -1647,6 +1647,10 @@ struct ResTable_overlayable_policy_header // The overlay must reside of the product partition or must have existed on the product // partition before an upgrade to overlay these resources. POLICY_PRODUCT_PARTITION = 0x00000008, // The overlay must be signed with the same signature as the actor of the target resource, // which can be separate or the same as the target package with the resource. POLICY_SIGNATURE = 0x00000010, }; uint32_t policy_flags; Loading
tools/aapt2/ResourceParser.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -1113,6 +1113,13 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource const std::string& element_name = parser->element_name(); const std::string& element_namespace = parser->element_namespace(); if (element_namespace.empty() && element_name == "item") { if (current_policies == OverlayableItem::Policy::kNone) { diag_->Error(DiagMessage(element_source) << "<item> within an <overlayable> must be inside a <policy> block"); error = true; continue; } // Items specify the name and type of resource that should be overlayable Maybe<StringPiece> item_name = xml::FindNonEmptyAttribute(parser, "name"); if (!item_name) { Loading Loading @@ -1169,6 +1176,8 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource current_policies |= OverlayableItem::Policy::kSystem; } else if (trimmed_part == "vendor") { current_policies |= OverlayableItem::Policy::kVendor; } else if (trimmed_part == "signature") { current_policies |= OverlayableItem::Policy::kSignature; } else { diag_->Error(DiagMessage(element_source) << "<policy> has unsupported type '" << trimmed_part << "'"); Loading @@ -1176,6 +1185,11 @@ bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource continue; } } } else { diag_->Error(DiagMessage(element_source) << "<policy> must have a 'type' attribute"); error = true; continue; } } else if (!ShouldIgnoreElement(element_namespace, element_name)) { diag_->Error(DiagMessage(element_source) << "invalid element <" << element_name << "> " Loading
tools/aapt2/ResourceParser_test.cpp +34 −14 Original line number Diff line number Diff line Loading @@ -894,8 +894,10 @@ TEST_F(ResourceParserTest, ParsePlatformIndependentNewline) { TEST_F(ResourceParserTest, ParseOverlayable) { std::string input = R"( <overlayable name="Name" actor="overlay://theme"> <policy type="signature"> <item type="string" name="foo" /> <item type="drawable" name="bar" /> </policy> </overlayable>)"; ASSERT_TRUE(TestParse(input)); Loading @@ -906,7 +908,7 @@ TEST_F(ResourceParserTest, ParseOverlayable) { OverlayableItem& result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); EXPECT_THAT(result_overlayable_item.overlayable->actor, Eq("overlay://theme")); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kNone)); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kSignature)); search_result = table_.FindResource(test::ParseNameOrDie("drawable/bar")); ASSERT_TRUE(search_result); Loading @@ -915,7 +917,7 @@ TEST_F(ResourceParserTest, ParseOverlayable) { result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); EXPECT_THAT(result_overlayable_item.overlayable->actor, Eq("overlay://theme")); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kNone)); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kSignature)); } TEST_F(ResourceParserTest, ParseOverlayableRequiresName) { Loading @@ -931,7 +933,6 @@ TEST_F(ResourceParserTest, ParseOverlayableBadActorFail) { TEST_F(ResourceParserTest, ParseOverlayablePolicy) { std::string input = R"( <overlayable name="Name"> <item type="string" name="foo" /> <policy type="product"> <item type="string" name="bar" /> </policy> Loading @@ -944,23 +945,18 @@ TEST_F(ResourceParserTest, ParseOverlayablePolicy) { <policy type="public"> <item type="string" name="faz" /> </policy> <policy type="signature"> <item type="string" name="foz" /> </policy> </overlayable>)"; ASSERT_TRUE(TestParse(input)); auto search_result = table_.FindResource(test::ParseNameOrDie("string/foo")); auto search_result = table_.FindResource(test::ParseNameOrDie("string/bar")); ASSERT_TRUE(search_result); ASSERT_THAT(search_result.value().entry, NotNull()); ASSERT_TRUE(search_result.value().entry->overlayable_item); OverlayableItem result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kNone)); search_result = table_.FindResource(test::ParseNameOrDie("string/bar")); ASSERT_TRUE(search_result); ASSERT_THAT(search_result.value().entry, NotNull()); ASSERT_TRUE(search_result.value().entry->overlayable_item); result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kProduct)); search_result = table_.FindResource(test::ParseNameOrDie("string/fiz")); Loading @@ -986,6 +982,30 @@ TEST_F(ResourceParserTest, ParseOverlayablePolicy) { result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kPublic)); search_result = table_.FindResource(test::ParseNameOrDie("string/foz")); ASSERT_TRUE(search_result); ASSERT_THAT(search_result.value().entry, NotNull()); ASSERT_TRUE(search_result.value().entry->overlayable_item); result_overlayable_item = search_result.value().entry->overlayable_item.value(); EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name")); EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kSignature)); } TEST_F(ResourceParserTest, ParseOverlayableNoPolicyError) { std::string input = R"( <overlayable name="Name"> <item type="string" name="foo" /> </overlayable>)"; EXPECT_FALSE(TestParse(input)); input = R"( <overlayable name="Name"> <policy> <item name="foo" /> </policy> </overlayable>)"; EXPECT_FALSE(TestParse(input)); } TEST_F(ResourceParserTest, ParseOverlayableBadPolicyError) { Loading
tools/aapt2/ResourceTable.h +3 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,9 @@ struct OverlayableItem { // The resource can be overlaid by any overlay on the product partition. kProduct = 0x08, // The resource can be overlaid by any overlay signed with the same signature as its actor. kSignature = 0x010, }; std::shared_ptr<Overlayable> overlayable; Loading
tools/aapt2/Resources.proto +2 −2 Original line number Diff line number Diff line Loading @@ -138,10 +138,10 @@ message AllowNew { // Represents a set of overlayable resources. message Overlayable { // The name of the <overlyabale>. // The name of the <overlayable>. string name = 1; // The location of the <overlyabale> declaration in the source. // The location of the <overlayable> declaration in the source. Source source = 2; // The component responsible for enabling and disabling overlays targeting this <overlayable>. Loading