1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "link/ReferenceLinker.h" 18 #include "test/Test.h" 19 20 using android::ResTable_map; 21 22 namespace aapt { 23 24 TEST(ReferenceLinkerTest, LinkSimpleReferences) { 25 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() 26 .setPackageId(u"com.app.test", 0x7f) 27 .addReference(u"@com.app.test:string/foo", ResourceId(0x7f020000), 28 u"@com.app.test:string/bar") 29 30 // Test use of local reference (w/o package name). 31 .addReference(u"@com.app.test:string/bar", ResourceId(0x7f020001), u"@string/baz") 32 33 .addReference(u"@com.app.test:string/baz", ResourceId(0x7f020002), 34 u"@android:string/ok") 35 .build(); 36 37 std::unique_ptr<IAaptContext> context = test::ContextBuilder() 38 .setCompilationPackage(u"com.app.test") 39 .setPackageId(0x7f) 40 .setNameManglerPolicy(NameManglerPolicy{ u"com.app.test" }) 41 .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) 42 .addSymbolSource(test::StaticSymbolSourceBuilder() 43 .addPublicSymbol(u"@android:string/ok", ResourceId(0x01040034)) 44 .build()) 45 .build(); 46 47 ReferenceLinker linker; 48 ASSERT_TRUE(linker.consume(context.get(), table.get())); 49 50 Reference* ref = test::getValue<Reference>(table.get(), u"@com.app.test:string/foo"); 51 ASSERT_NE(ref, nullptr); 52 AAPT_ASSERT_TRUE(ref->id); 53 EXPECT_EQ(ref->id.value(), ResourceId(0x7f020001)); 54 55 ref = test::getValue<Reference>(table.get(), u"@com.app.test:string/bar"); 56 ASSERT_NE(ref, nullptr); 57 AAPT_ASSERT_TRUE(ref->id); 58 EXPECT_EQ(ref->id.value(), ResourceId(0x7f020002)); 59 60 ref = test::getValue<Reference>(table.get(), u"@com.app.test:string/baz"); 61 ASSERT_NE(ref, nullptr); 62 AAPT_ASSERT_TRUE(ref->id); 63 EXPECT_EQ(ref->id.value(), ResourceId(0x01040034)); 64 } 65 66 TEST(ReferenceLinkerTest, LinkStyleAttributes) { 67 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() 68 .setPackageId(u"com.app.test", 0x7f) 69 .addValue(u"@com.app.test:style/Theme", test::StyleBuilder() 70 .setParent(u"@android:style/Theme.Material") 71 .addItem(u"@android:attr/foo", ResourceUtils::tryParseColor(u"#ff00ff")) 72 .addItem(u"@android:attr/bar", {} /* placeholder */) 73 .build()) 74 .build(); 75 76 { 77 // We need to fill in the value for the attribute android:attr/bar after we build the 78 // table, because we need access to the string pool. 79 Style* style = test::getValue<Style>(table.get(), u"@com.app.test:style/Theme"); 80 ASSERT_NE(style, nullptr); 81 style->entries.back().value = util::make_unique<RawString>( 82 table->stringPool.makeRef(u"one|two")); 83 } 84 85 std::unique_ptr<IAaptContext> context = test::ContextBuilder() 86 .setCompilationPackage(u"com.app.test") 87 .setPackageId(0x7f) 88 .setNameManglerPolicy(NameManglerPolicy{ u"com.app.test" }) 89 .addSymbolSource(test::StaticSymbolSourceBuilder() 90 .addPublicSymbol(u"@android:style/Theme.Material", 91 ResourceId(0x01060000)) 92 .addPublicSymbol(u"@android:attr/foo", ResourceId(0x01010001), 93 test::AttributeBuilder() 94 .setTypeMask(ResTable_map::TYPE_COLOR) 95 .build()) 96 .addPublicSymbol(u"@android:attr/bar", ResourceId(0x01010002), 97 test::AttributeBuilder() 98 .setTypeMask(ResTable_map::TYPE_FLAGS) 99 .addItem(u"one", 0x01) 100 .addItem(u"two", 0x02) 101 .build()) 102 .build()) 103 .build(); 104 105 ReferenceLinker linker; 106 ASSERT_TRUE(linker.consume(context.get(), table.get())); 107 108 Style* style = test::getValue<Style>(table.get(), u"@com.app.test:style/Theme"); 109 ASSERT_NE(style, nullptr); 110 AAPT_ASSERT_TRUE(style->parent); 111 AAPT_ASSERT_TRUE(style->parent.value().id); 112 EXPECT_EQ(style->parent.value().id.value(), ResourceId(0x01060000)); 113 114 ASSERT_EQ(2u, style->entries.size()); 115 116 AAPT_ASSERT_TRUE(style->entries[0].key.id); 117 EXPECT_EQ(style->entries[0].key.id.value(), ResourceId(0x01010001)); 118 ASSERT_NE(valueCast<BinaryPrimitive>(style->entries[0].value.get()), nullptr); 119 120 AAPT_ASSERT_TRUE(style->entries[1].key.id); 121 EXPECT_EQ(style->entries[1].key.id.value(), ResourceId(0x01010002)); 122 ASSERT_NE(valueCast<BinaryPrimitive>(style->entries[1].value.get()), nullptr); 123 } 124 125 TEST(ReferenceLinkerTest, LinkMangledReferencesAndAttributes) { 126 std::unique_ptr<IAaptContext> context = test::ContextBuilder() 127 .setCompilationPackage(u"com.app.test") 128 .setPackageId(0x7f) 129 .setNameManglerPolicy(NameManglerPolicy{ u"com.app.test", { u"com.android.support" } }) 130 .addSymbolSource(test::StaticSymbolSourceBuilder() 131 .addPublicSymbol(u"@com.app.test:attr/com.android.support$foo", 132 ResourceId(0x7f010000), 133 test::AttributeBuilder() 134 .setTypeMask(ResTable_map::TYPE_COLOR) 135 .build()) 136 .build()) 137 .build(); 138 139 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() 140 .setPackageId(u"com.app.test", 0x7f) 141 .addValue(u"@com.app.test:style/Theme", ResourceId(0x7f020000), 142 test::StyleBuilder().addItem(u"@com.android.support:attr/foo", 143 ResourceUtils::tryParseColor(u"#ff0000")) 144 .build()) 145 .build(); 146 147 ReferenceLinker linker; 148 ASSERT_TRUE(linker.consume(context.get(), table.get())); 149 150 Style* style = test::getValue<Style>(table.get(), u"@com.app.test:style/Theme"); 151 ASSERT_NE(style, nullptr); 152 ASSERT_EQ(1u, style->entries.size()); 153 AAPT_ASSERT_TRUE(style->entries.front().key.id); 154 EXPECT_EQ(style->entries.front().key.id.value(), ResourceId(0x7f010000)); 155 } 156 157 TEST(ReferenceLinkerTest, FailToLinkPrivateSymbols) { 158 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() 159 .setPackageId(u"com.app.test", 0x7f) 160 .addReference(u"@com.app.test:string/foo", ResourceId(0x7f020000), 161 u"@android:string/hidden") 162 .build(); 163 164 std::unique_ptr<IAaptContext> context = test::ContextBuilder() 165 .setCompilationPackage(u"com.app.test") 166 .setPackageId(0x7f) 167 .setNameManglerPolicy(NameManglerPolicy{ u"com.app.test" }) 168 .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) 169 .addSymbolSource(test::StaticSymbolSourceBuilder() 170 .addSymbol(u"@android:string/hidden", ResourceId(0x01040034)) 171 .build()) 172 .build(); 173 174 ReferenceLinker linker; 175 ASSERT_FALSE(linker.consume(context.get(), table.get())); 176 } 177 178 TEST(ReferenceLinkerTest, FailToLinkPrivateMangledSymbols) { 179 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() 180 .setPackageId(u"com.app.test", 0x7f) 181 .addReference(u"@com.app.test:string/foo", ResourceId(0x7f020000), 182 u"@com.app.lib:string/hidden") 183 .build(); 184 185 std::unique_ptr<IAaptContext> context = test::ContextBuilder() 186 .setCompilationPackage(u"com.app.test") 187 .setPackageId(0x7f) 188 .setNameManglerPolicy(NameManglerPolicy{ u"com.app.test", { u"com.app.lib" } }) 189 .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) 190 .addSymbolSource(test::StaticSymbolSourceBuilder() 191 .addSymbol(u"@com.app.test:string/com.app.lib$hidden", 192 ResourceId(0x7f040034)) 193 .build()) 194 195 .build(); 196 197 ReferenceLinker linker; 198 ASSERT_FALSE(linker.consume(context.get(), table.get())); 199 } 200 201 TEST(ReferenceLinkerTest, FailToLinkPrivateStyleAttributes) { 202 std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() 203 .setPackageId(u"com.app.test", 0x7f) 204 .addValue(u"@com.app.test:style/Theme", test::StyleBuilder() 205 .addItem(u"@android:attr/hidden", ResourceUtils::tryParseColor(u"#ff00ff")) 206 .build()) 207 .build(); 208 209 std::unique_ptr<IAaptContext> context = test::ContextBuilder() 210 .setCompilationPackage(u"com.app.test") 211 .setPackageId(0x7f) 212 .setNameManglerPolicy(NameManglerPolicy{ u"com.app.test" }) 213 .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) 214 .addSymbolSource(test::StaticSymbolSourceBuilder() 215 .addSymbol(u"@android:attr/hidden", ResourceId(0x01010001), 216 test::AttributeBuilder() 217 .setTypeMask( 218 android::ResTable_map::TYPE_COLOR) 219 .build()) 220 .build()) 221 .build(); 222 223 ReferenceLinker linker; 224 ASSERT_FALSE(linker.consume(context.get(), table.get())); 225 } 226 227 } // namespace aapt 228