Home | History | Annotate | Download | only in link
      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