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/ManifestFixer.h"
     18 #include "test/Builders.h"
     19 #include "test/Context.h"
     20 
     21 #include <gtest/gtest.h>
     22 
     23 namespace aapt {
     24 
     25 struct ManifestFixerTest : public ::testing::Test {
     26     std::unique_ptr<IAaptContext> mContext;
     27 
     28     void SetUp() override {
     29         mContext = test::ContextBuilder()
     30                 .setCompilationPackage(u"android")
     31                 .setPackageId(0x01)
     32                 .setNameManglerPolicy(NameManglerPolicy{ u"android" })
     33                 .addSymbolSource(test::StaticSymbolSourceBuilder()
     34                         .addSymbol(u"@android:attr/package", ResourceId(0x01010000),
     35                                    test::AttributeBuilder()
     36                                         .setTypeMask(android::ResTable_map::TYPE_STRING)
     37                                         .build())
     38                         .addSymbol(u"@android:attr/minSdkVersion", ResourceId(0x01010001),
     39                                    test::AttributeBuilder()
     40                                         .setTypeMask(android::ResTable_map::TYPE_STRING |
     41                                                      android::ResTable_map::TYPE_INTEGER)
     42                                         .build())
     43                         .addSymbol(u"@android:attr/targetSdkVersion", ResourceId(0x01010002),
     44                                    test::AttributeBuilder()
     45                                         .setTypeMask(android::ResTable_map::TYPE_STRING |
     46                                                      android::ResTable_map::TYPE_INTEGER)
     47                                         .build())
     48                         .addSymbol(u"@android:string/str", ResourceId(0x01060000))
     49                         .build())
     50                 .build();
     51     }
     52 
     53     std::unique_ptr<xml::XmlResource> verify(const StringPiece& str) {
     54         return verifyWithOptions(str, {});
     55     }
     56 
     57     std::unique_ptr<xml::XmlResource> verifyWithOptions(const StringPiece& str,
     58                                                         const ManifestFixerOptions& options) {
     59         std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(str);
     60         ManifestFixer fixer(options);
     61         if (fixer.consume(mContext.get(), doc.get())) {
     62             return doc;
     63         }
     64         return {};
     65     }
     66 };
     67 
     68 TEST_F(ManifestFixerTest, EnsureManifestIsRootTag) {
     69     EXPECT_EQ(nullptr, verify("<other-tag />"));
     70     EXPECT_EQ(nullptr, verify("<ns:manifest xmlns:ns=\"com\" />"));
     71     EXPECT_NE(nullptr, verify("<manifest package=\"android\"></manifest>"));
     72 }
     73 
     74 TEST_F(ManifestFixerTest, EnsureManifestHasPackage) {
     75     EXPECT_NE(nullptr, verify("<manifest package=\"android\" />"));
     76     EXPECT_NE(nullptr, verify("<manifest package=\"com.android\" />"));
     77     EXPECT_NE(nullptr, verify("<manifest package=\"com.android.google\" />"));
     78     EXPECT_EQ(nullptr, verify("<manifest package=\"com.android.google.Class$1\" />"));
     79     EXPECT_EQ(nullptr,
     80               verify("<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" "
     81                      "android:package=\"com.android\" />"));
     82     EXPECT_EQ(nullptr, verify("<manifest package=\"@string/str\" />"));
     83 }
     84 
     85 TEST_F(ManifestFixerTest, UseDefaultSdkVersionsIfNonePresent) {
     86     ManifestFixerOptions options = { std::u16string(u"8"), std::u16string(u"22") };
     87 
     88     std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
     89       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     90                 package="android">
     91         <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="21" />
     92       </manifest>)EOF", options);
     93     ASSERT_NE(nullptr, doc);
     94 
     95     xml::Element* el;
     96     xml::Attribute* attr;
     97 
     98     el = xml::findRootElement(doc.get());
     99     ASSERT_NE(nullptr, el);
    100     el = el->findChild({}, u"uses-sdk");
    101     ASSERT_NE(nullptr, el);
    102     attr = el->findAttribute(xml::kSchemaAndroid, u"minSdkVersion");
    103     ASSERT_NE(nullptr, attr);
    104     EXPECT_EQ(u"7", attr->value);
    105     attr = el->findAttribute(xml::kSchemaAndroid, u"targetSdkVersion");
    106     ASSERT_NE(nullptr, attr);
    107     EXPECT_EQ(u"21", attr->value);
    108 
    109     doc = verifyWithOptions(R"EOF(
    110       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    111                 package="android">
    112         <uses-sdk android:targetSdkVersion="21" />
    113       </manifest>)EOF", options);
    114     ASSERT_NE(nullptr, doc);
    115 
    116     el = xml::findRootElement(doc.get());
    117     ASSERT_NE(nullptr, el);
    118     el = el->findChild({}, u"uses-sdk");
    119     ASSERT_NE(nullptr, el);
    120     attr = el->findAttribute(xml::kSchemaAndroid, u"minSdkVersion");
    121     ASSERT_NE(nullptr, attr);
    122     EXPECT_EQ(u"8", attr->value);
    123     attr = el->findAttribute(xml::kSchemaAndroid, u"targetSdkVersion");
    124     ASSERT_NE(nullptr, attr);
    125     EXPECT_EQ(u"21", attr->value);
    126 
    127     doc = verifyWithOptions(R"EOF(
    128       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    129                 package="android">
    130         <uses-sdk />
    131       </manifest>)EOF", options);
    132     ASSERT_NE(nullptr, doc);
    133 
    134     el = xml::findRootElement(doc.get());
    135     ASSERT_NE(nullptr, el);
    136     el = el->findChild({}, u"uses-sdk");
    137     ASSERT_NE(nullptr, el);
    138     attr = el->findAttribute(xml::kSchemaAndroid, u"minSdkVersion");
    139     ASSERT_NE(nullptr, attr);
    140     EXPECT_EQ(u"8", attr->value);
    141     attr = el->findAttribute(xml::kSchemaAndroid, u"targetSdkVersion");
    142     ASSERT_NE(nullptr, attr);
    143     EXPECT_EQ(u"22", attr->value);
    144 
    145     doc = verifyWithOptions(R"EOF(
    146       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    147                 package="android" />)EOF", options);
    148     ASSERT_NE(nullptr, doc);
    149 
    150     el = xml::findRootElement(doc.get());
    151     ASSERT_NE(nullptr, el);
    152     el = el->findChild({}, u"uses-sdk");
    153     ASSERT_NE(nullptr, el);
    154     attr = el->findAttribute(xml::kSchemaAndroid, u"minSdkVersion");
    155     ASSERT_NE(nullptr, attr);
    156     EXPECT_EQ(u"8", attr->value);
    157     attr = el->findAttribute(xml::kSchemaAndroid, u"targetSdkVersion");
    158     ASSERT_NE(nullptr, attr);
    159     EXPECT_EQ(u"22", attr->value);
    160 }
    161 
    162 TEST_F(ManifestFixerTest, RenameManifestPackageAndFullyQualifyClasses) {
    163     ManifestFixerOptions options;
    164     options.renameManifestPackage = std::u16string(u"com.android");
    165 
    166     std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
    167       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    168                 package="android">
    169         <application android:name=".MainApplication" text="hello">
    170           <activity android:name=".activity.Start" />
    171           <receiver android:name="com.google.android.Receiver" />
    172         </application>
    173       </manifest>)EOF", options);
    174     ASSERT_NE(nullptr, doc);
    175 
    176     xml::Element* manifestEl = xml::findRootElement(doc.get());
    177     ASSERT_NE(nullptr, manifestEl);
    178 
    179     xml::Attribute* attr = nullptr;
    180 
    181     attr = manifestEl->findAttribute({}, u"package");
    182     ASSERT_NE(nullptr, attr);
    183     EXPECT_EQ(std::u16string(u"com.android"), attr->value);
    184 
    185     xml::Element* applicationEl = manifestEl->findChild({}, u"application");
    186     ASSERT_NE(nullptr, applicationEl);
    187 
    188     attr = applicationEl->findAttribute(xml::kSchemaAndroid, u"name");
    189     ASSERT_NE(nullptr, attr);
    190     EXPECT_EQ(std::u16string(u"android.MainApplication"), attr->value);
    191 
    192     attr = applicationEl->findAttribute({}, u"text");
    193     ASSERT_NE(nullptr, attr);
    194     EXPECT_EQ(std::u16string(u"hello"), attr->value);
    195 
    196     xml::Element* el;
    197     el = applicationEl->findChild({}, u"activity");
    198     ASSERT_NE(nullptr, el);
    199 
    200     attr = el->findAttribute(xml::kSchemaAndroid, u"name");
    201     ASSERT_NE(nullptr, el);
    202     EXPECT_EQ(std::u16string(u"android.activity.Start"), attr->value);
    203 
    204     el = applicationEl->findChild({}, u"receiver");
    205     ASSERT_NE(nullptr, el);
    206 
    207     attr = el->findAttribute(xml::kSchemaAndroid, u"name");
    208     ASSERT_NE(nullptr, el);
    209     EXPECT_EQ(std::u16string(u"com.google.android.Receiver"), attr->value);
    210 }
    211 
    212 TEST_F(ManifestFixerTest, RenameManifestInstrumentationPackageAndFullyQualifyTarget) {
    213     ManifestFixerOptions options;
    214     options.renameInstrumentationTargetPackage = std::u16string(u"com.android");
    215 
    216     std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
    217       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    218                 package="android">
    219         <instrumentation android:targetPackage="android" />
    220       </manifest>)EOF", options);
    221     ASSERT_NE(nullptr, doc);
    222 
    223     xml::Element* manifestEl = xml::findRootElement(doc.get());
    224     ASSERT_NE(nullptr, manifestEl);
    225 
    226     xml::Element* instrumentationEl = manifestEl->findChild({}, u"instrumentation");
    227     ASSERT_NE(nullptr, instrumentationEl);
    228 
    229     xml::Attribute* attr = instrumentationEl->findAttribute(xml::kSchemaAndroid, u"targetPackage");
    230     ASSERT_NE(nullptr, attr);
    231     EXPECT_EQ(std::u16string(u"com.android"), attr->value);
    232 }
    233 
    234 TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) {
    235     ManifestFixerOptions options;
    236     options.versionNameDefault = std::u16string(u"Beta");
    237     options.versionCodeDefault = std::u16string(u"0x10000000");
    238 
    239     std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
    240       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    241                 package="android" />)EOF", options);
    242     ASSERT_NE(nullptr, doc);
    243 
    244     xml::Element* manifestEl = xml::findRootElement(doc.get());
    245     ASSERT_NE(nullptr, manifestEl);
    246 
    247     xml::Attribute* attr = manifestEl->findAttribute(xml::kSchemaAndroid, u"versionName");
    248     ASSERT_NE(nullptr, attr);
    249     EXPECT_EQ(std::u16string(u"Beta"), attr->value);
    250 
    251     attr = manifestEl->findAttribute(xml::kSchemaAndroid, u"versionCode");
    252     ASSERT_NE(nullptr, attr);
    253     EXPECT_EQ(std::u16string(u"0x10000000"), attr->value);
    254 }
    255 
    256 } // namespace aapt
    257