ManifestFixer_test.cpp revision ce5e56e243d262a9b65459c3bd0bb9eaadd40628
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
19#include "test/Test.h"
20
21namespace aapt {
22
23struct ManifestFixerTest : public ::testing::Test {
24  std::unique_ptr<IAaptContext> mContext;
25
26  void SetUp() override {
27    mContext =
28        test::ContextBuilder()
29            .SetCompilationPackage("android")
30            .SetPackageId(0x01)
31            .SetNameManglerPolicy(NameManglerPolicy{"android"})
32            .AddSymbolSource(
33                test::StaticSymbolSourceBuilder()
34                    .AddSymbol(
35                        "android:attr/package", ResourceId(0x01010000),
36                        test::AttributeBuilder()
37                            .SetTypeMask(android::ResTable_map::TYPE_STRING)
38                            .Build())
39                    .AddSymbol(
40                        "android:attr/minSdkVersion", ResourceId(0x01010001),
41                        test::AttributeBuilder()
42                            .SetTypeMask(android::ResTable_map::TYPE_STRING |
43                                         android::ResTable_map::TYPE_INTEGER)
44                            .Build())
45                    .AddSymbol(
46                        "android:attr/targetSdkVersion", ResourceId(0x01010002),
47                        test::AttributeBuilder()
48                            .SetTypeMask(android::ResTable_map::TYPE_STRING |
49                                         android::ResTable_map::TYPE_INTEGER)
50                            .Build())
51                    .AddSymbol("android:string/str", ResourceId(0x01060000))
52                    .Build())
53            .Build();
54  }
55
56  std::unique_ptr<xml::XmlResource> Verify(const StringPiece& str) {
57    return VerifyWithOptions(str, {});
58  }
59
60  std::unique_ptr<xml::XmlResource> VerifyWithOptions(
61      const StringPiece& str, const ManifestFixerOptions& options) {
62    std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(str);
63    ManifestFixer fixer(options);
64    if (fixer.Consume(mContext.get(), doc.get())) {
65      return doc;
66    }
67    return {};
68  }
69};
70
71TEST_F(ManifestFixerTest, EnsureManifestIsRootTag) {
72  EXPECT_EQ(nullptr, Verify("<other-tag />"));
73  EXPECT_EQ(nullptr, Verify("<ns:manifest xmlns:ns=\"com\" />"));
74  EXPECT_NE(nullptr, Verify("<manifest package=\"android\"></manifest>"));
75}
76
77TEST_F(ManifestFixerTest, EnsureManifestHasPackage) {
78  EXPECT_NE(nullptr, Verify("<manifest package=\"android\" />"));
79  EXPECT_NE(nullptr, Verify("<manifest package=\"com.android\" />"));
80  EXPECT_NE(nullptr, Verify("<manifest package=\"com.android.google\" />"));
81  EXPECT_EQ(nullptr,
82            Verify("<manifest package=\"com.android.google.Class$1\" />"));
83  EXPECT_EQ(nullptr, Verify("<manifest "
84                            "xmlns:android=\"http://schemas.android.com/apk/"
85                            "res/android\" "
86                            "android:package=\"com.android\" />"));
87  EXPECT_EQ(nullptr, Verify("<manifest package=\"@string/str\" />"));
88}
89
90TEST_F(ManifestFixerTest, UseDefaultSdkVersionsIfNonePresent) {
91  ManifestFixerOptions options = {std::string("8"), std::string("22")};
92
93  std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
94      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
95                package="android">
96        <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="21" />
97      </manifest>)EOF",
98                                                            options);
99  ASSERT_NE(nullptr, doc);
100
101  xml::Element* el;
102  xml::Attribute* attr;
103
104  el = xml::FindRootElement(doc.get());
105  ASSERT_NE(nullptr, el);
106  el = el->FindChild({}, "uses-sdk");
107  ASSERT_NE(nullptr, el);
108  attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
109  ASSERT_NE(nullptr, attr);
110  EXPECT_EQ("7", attr->value);
111  attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
112  ASSERT_NE(nullptr, attr);
113  EXPECT_EQ("21", attr->value);
114
115  doc = VerifyWithOptions(R"EOF(
116      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
117                package="android">
118        <uses-sdk android:targetSdkVersion="21" />
119      </manifest>)EOF",
120                          options);
121  ASSERT_NE(nullptr, doc);
122
123  el = xml::FindRootElement(doc.get());
124  ASSERT_NE(nullptr, el);
125  el = el->FindChild({}, "uses-sdk");
126  ASSERT_NE(nullptr, el);
127  attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
128  ASSERT_NE(nullptr, attr);
129  EXPECT_EQ("8", attr->value);
130  attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
131  ASSERT_NE(nullptr, attr);
132  EXPECT_EQ("21", attr->value);
133
134  doc = VerifyWithOptions(R"EOF(
135      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
136                package="android">
137        <uses-sdk />
138      </manifest>)EOF",
139                          options);
140  ASSERT_NE(nullptr, doc);
141
142  el = xml::FindRootElement(doc.get());
143  ASSERT_NE(nullptr, el);
144  el = el->FindChild({}, "uses-sdk");
145  ASSERT_NE(nullptr, el);
146  attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
147  ASSERT_NE(nullptr, attr);
148  EXPECT_EQ("8", attr->value);
149  attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
150  ASSERT_NE(nullptr, attr);
151  EXPECT_EQ("22", attr->value);
152
153  doc = VerifyWithOptions(R"EOF(
154      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
155                package="android" />)EOF",
156                          options);
157  ASSERT_NE(nullptr, doc);
158
159  el = xml::FindRootElement(doc.get());
160  ASSERT_NE(nullptr, el);
161  el = el->FindChild({}, "uses-sdk");
162  ASSERT_NE(nullptr, el);
163  attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
164  ASSERT_NE(nullptr, attr);
165  EXPECT_EQ("8", attr->value);
166  attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
167  ASSERT_NE(nullptr, attr);
168  EXPECT_EQ("22", attr->value);
169}
170
171TEST_F(ManifestFixerTest, RenameManifestPackageAndFullyQualifyClasses) {
172  ManifestFixerOptions options;
173  options.rename_manifest_package = std::string("com.android");
174
175  std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
176      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
177                package="android">
178        <application android:name=".MainApplication" text="hello">
179          <activity android:name=".activity.Start" />
180          <receiver android:name="com.google.android.Receiver" />
181        </application>
182      </manifest>)EOF",
183                                                            options);
184  ASSERT_NE(nullptr, doc);
185
186  xml::Element* manifestEl = xml::FindRootElement(doc.get());
187  ASSERT_NE(nullptr, manifestEl);
188
189  xml::Attribute* attr = nullptr;
190
191  attr = manifestEl->FindAttribute({}, "package");
192  ASSERT_NE(nullptr, attr);
193  EXPECT_EQ(std::string("com.android"), attr->value);
194
195  xml::Element* applicationEl = manifestEl->FindChild({}, "application");
196  ASSERT_NE(nullptr, applicationEl);
197
198  attr = applicationEl->FindAttribute(xml::kSchemaAndroid, "name");
199  ASSERT_NE(nullptr, attr);
200  EXPECT_EQ(std::string("android.MainApplication"), attr->value);
201
202  attr = applicationEl->FindAttribute({}, "text");
203  ASSERT_NE(nullptr, attr);
204  EXPECT_EQ(std::string("hello"), attr->value);
205
206  xml::Element* el;
207  el = applicationEl->FindChild({}, "activity");
208  ASSERT_NE(nullptr, el);
209
210  attr = el->FindAttribute(xml::kSchemaAndroid, "name");
211  ASSERT_NE(nullptr, el);
212  EXPECT_EQ(std::string("android.activity.Start"), attr->value);
213
214  el = applicationEl->FindChild({}, "receiver");
215  ASSERT_NE(nullptr, el);
216
217  attr = el->FindAttribute(xml::kSchemaAndroid, "name");
218  ASSERT_NE(nullptr, el);
219  EXPECT_EQ(std::string("com.google.android.Receiver"), attr->value);
220}
221
222TEST_F(ManifestFixerTest,
223       RenameManifestInstrumentationPackageAndFullyQualifyTarget) {
224  ManifestFixerOptions options;
225  options.rename_instrumentation_target_package = std::string("com.android");
226
227  std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
228      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
229                package="android">
230        <instrumentation android:targetPackage="android" />
231      </manifest>)EOF",
232                                                            options);
233  ASSERT_NE(nullptr, doc);
234
235  xml::Element* manifest_el = xml::FindRootElement(doc.get());
236  ASSERT_NE(nullptr, manifest_el);
237
238  xml::Element* instrumentation_el =
239      manifest_el->FindChild({}, "instrumentation");
240  ASSERT_NE(nullptr, instrumentation_el);
241
242  xml::Attribute* attr =
243      instrumentation_el->FindAttribute(xml::kSchemaAndroid, "targetPackage");
244  ASSERT_NE(nullptr, attr);
245  EXPECT_EQ(std::string("com.android"), attr->value);
246}
247
248TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) {
249  ManifestFixerOptions options;
250  options.version_name_default = std::string("Beta");
251  options.version_code_default = std::string("0x10000000");
252
253  std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
254      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
255                package="android" />)EOF",
256                                                            options);
257  ASSERT_NE(nullptr, doc);
258
259  xml::Element* manifest_el = xml::FindRootElement(doc.get());
260  ASSERT_NE(nullptr, manifest_el);
261
262  xml::Attribute* attr =
263      manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
264  ASSERT_NE(nullptr, attr);
265  EXPECT_EQ(std::string("Beta"), attr->value);
266
267  attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
268  ASSERT_NE(nullptr, attr);
269  EXPECT_EQ(std::string("0x10000000"), attr->value);
270}
271
272TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) {
273  EXPECT_EQ(nullptr,
274            Verify("<manifest package=\"android\" coreApp=\"hello\" />"));
275  EXPECT_EQ(nullptr,
276            Verify("<manifest package=\"android\" coreApp=\"1dp\" />"));
277
278  std::unique_ptr<xml::XmlResource> doc =
279      Verify("<manifest package=\"android\" coreApp=\"true\" />");
280  ASSERT_NE(nullptr, doc);
281
282  xml::Element* el = xml::FindRootElement(doc.get());
283  ASSERT_NE(nullptr, el);
284
285  EXPECT_EQ("manifest", el->name);
286
287  xml::Attribute* attr = el->FindAttribute("", "coreApp");
288  ASSERT_NE(nullptr, attr);
289
290  EXPECT_NE(nullptr, attr->compiled_value);
291  EXPECT_NE(nullptr, ValueCast<BinaryPrimitive>(attr->compiled_value.get()));
292}
293
294}  // namespace aapt
295