blob: dc78d98aaed6432b1a1d04eeb0f22b51dad4a09c [file] [log] [blame]
Adam Lesinski2ae4a872015-11-02 16:10:55 -08001/*
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"
Adam Lesinski2ae4a872015-11-02 16:10:55 -080018#include "test/Builders.h"
19#include "test/Context.h"
20
21#include <gtest/gtest.h>
22
23namespace aapt {
24
25struct ManifestFixerTest : public ::testing::Test {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070026 std::unique_ptr<IAaptContext> mContext;
Adam Lesinski2ae4a872015-11-02 16:10:55 -080027
Adam Lesinskicacb28f2016-10-19 12:18:14 -070028 void SetUp() override {
29 mContext =
30 test::ContextBuilder()
31 .setCompilationPackage("android")
32 .setPackageId(0x01)
33 .setNameManglerPolicy(NameManglerPolicy{"android"})
34 .addSymbolSource(
35 test::StaticSymbolSourceBuilder()
36 .addSymbol(
37 "android:attr/package", ResourceId(0x01010000),
38 test::AttributeBuilder()
39 .setTypeMask(android::ResTable_map::TYPE_STRING)
40 .build())
41 .addSymbol(
42 "android:attr/minSdkVersion", ResourceId(0x01010001),
43 test::AttributeBuilder()
44 .setTypeMask(android::ResTable_map::TYPE_STRING |
45 android::ResTable_map::TYPE_INTEGER)
46 .build())
47 .addSymbol(
48 "android:attr/targetSdkVersion", ResourceId(0x01010002),
49 test::AttributeBuilder()
50 .setTypeMask(android::ResTable_map::TYPE_STRING |
51 android::ResTable_map::TYPE_INTEGER)
52 .build())
53 .addSymbol("android:string/str", ResourceId(0x01060000))
54 .build())
55 .build();
56 }
Adam Lesinski2ae4a872015-11-02 16:10:55 -080057
Adam Lesinskicacb28f2016-10-19 12:18:14 -070058 std::unique_ptr<xml::XmlResource> verify(const StringPiece& str) {
59 return verifyWithOptions(str, {});
60 }
Adam Lesinski2ae4a872015-11-02 16:10:55 -080061
Adam Lesinskicacb28f2016-10-19 12:18:14 -070062 std::unique_ptr<xml::XmlResource> verifyWithOptions(
63 const StringPiece& str, const ManifestFixerOptions& options) {
64 std::unique_ptr<xml::XmlResource> doc = test::buildXmlDom(str);
65 ManifestFixer fixer(options);
66 if (fixer.consume(mContext.get(), doc.get())) {
67 return doc;
Adam Lesinski2ae4a872015-11-02 16:10:55 -080068 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -070069 return {};
70 }
Adam Lesinski2ae4a872015-11-02 16:10:55 -080071};
72
73TEST_F(ManifestFixerTest, EnsureManifestIsRootTag) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070074 EXPECT_EQ(nullptr, verify("<other-tag />"));
75 EXPECT_EQ(nullptr, verify("<ns:manifest xmlns:ns=\"com\" />"));
76 EXPECT_NE(nullptr, verify("<manifest package=\"android\"></manifest>"));
Adam Lesinski2ae4a872015-11-02 16:10:55 -080077}
78
79TEST_F(ManifestFixerTest, EnsureManifestHasPackage) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070080 EXPECT_NE(nullptr, verify("<manifest package=\"android\" />"));
81 EXPECT_NE(nullptr, verify("<manifest package=\"com.android\" />"));
82 EXPECT_NE(nullptr, verify("<manifest package=\"com.android.google\" />"));
83 EXPECT_EQ(nullptr,
84 verify("<manifest package=\"com.android.google.Class$1\" />"));
85 EXPECT_EQ(nullptr, verify("<manifest "
86 "xmlns:android=\"http://schemas.android.com/apk/"
87 "res/android\" "
88 "android:package=\"com.android\" />"));
89 EXPECT_EQ(nullptr, verify("<manifest package=\"@string/str\" />"));
Adam Lesinski2ae4a872015-11-02 16:10:55 -080090}
91
Adam Lesinski2ae4a872015-11-02 16:10:55 -080092TEST_F(ManifestFixerTest, UseDefaultSdkVersionsIfNonePresent) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070093 ManifestFixerOptions options = {std::string("8"), std::string("22")};
Adam Lesinski2ae4a872015-11-02 16:10:55 -080094
Adam Lesinskicacb28f2016-10-19 12:18:14 -070095 std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
Adam Lesinski2ae4a872015-11-02 16:10:55 -080096 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
97 package="android">
98 <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="21" />
Adam Lesinskicacb28f2016-10-19 12:18:14 -070099 </manifest>)EOF",
100 options);
101 ASSERT_NE(nullptr, doc);
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800102
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700103 xml::Element* el;
104 xml::Attribute* attr;
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800105
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700106 el = xml::findRootElement(doc.get());
107 ASSERT_NE(nullptr, el);
108 el = el->findChild({}, "uses-sdk");
109 ASSERT_NE(nullptr, el);
110 attr = el->findAttribute(xml::kSchemaAndroid, "minSdkVersion");
111 ASSERT_NE(nullptr, attr);
112 EXPECT_EQ("7", attr->value);
113 attr = el->findAttribute(xml::kSchemaAndroid, "targetSdkVersion");
114 ASSERT_NE(nullptr, attr);
115 EXPECT_EQ("21", attr->value);
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800116
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700117 doc = verifyWithOptions(R"EOF(
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800118 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
119 package="android">
120 <uses-sdk android:targetSdkVersion="21" />
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700121 </manifest>)EOF",
122 options);
123 ASSERT_NE(nullptr, doc);
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800124
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700125 el = xml::findRootElement(doc.get());
126 ASSERT_NE(nullptr, el);
127 el = el->findChild({}, "uses-sdk");
128 ASSERT_NE(nullptr, el);
129 attr = el->findAttribute(xml::kSchemaAndroid, "minSdkVersion");
130 ASSERT_NE(nullptr, attr);
131 EXPECT_EQ("8", attr->value);
132 attr = el->findAttribute(xml::kSchemaAndroid, "targetSdkVersion");
133 ASSERT_NE(nullptr, attr);
134 EXPECT_EQ("21", attr->value);
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800135
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700136 doc = verifyWithOptions(R"EOF(
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800137 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
138 package="android">
139 <uses-sdk />
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700140 </manifest>)EOF",
141 options);
142 ASSERT_NE(nullptr, doc);
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800143
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700144 el = xml::findRootElement(doc.get());
145 ASSERT_NE(nullptr, el);
146 el = el->findChild({}, "uses-sdk");
147 ASSERT_NE(nullptr, el);
148 attr = el->findAttribute(xml::kSchemaAndroid, "minSdkVersion");
149 ASSERT_NE(nullptr, attr);
150 EXPECT_EQ("8", attr->value);
151 attr = el->findAttribute(xml::kSchemaAndroid, "targetSdkVersion");
152 ASSERT_NE(nullptr, attr);
153 EXPECT_EQ("22", attr->value);
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800154
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700155 doc = verifyWithOptions(R"EOF(
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800156 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700157 package="android" />)EOF",
158 options);
159 ASSERT_NE(nullptr, doc);
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800160
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700161 el = xml::findRootElement(doc.get());
162 ASSERT_NE(nullptr, el);
163 el = el->findChild({}, "uses-sdk");
164 ASSERT_NE(nullptr, el);
165 attr = el->findAttribute(xml::kSchemaAndroid, "minSdkVersion");
166 ASSERT_NE(nullptr, attr);
167 EXPECT_EQ("8", attr->value);
168 attr = el->findAttribute(xml::kSchemaAndroid, "targetSdkVersion");
169 ASSERT_NE(nullptr, attr);
170 EXPECT_EQ("22", attr->value);
Adam Lesinski2ae4a872015-11-02 16:10:55 -0800171}
172
Adam Lesinski52364f72016-01-11 13:10:24 -0800173TEST_F(ManifestFixerTest, RenameManifestPackageAndFullyQualifyClasses) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700174 ManifestFixerOptions options;
175 options.renameManifestPackage = std::string("com.android");
Adam Lesinski52364f72016-01-11 13:10:24 -0800176
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700177 std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
Adam Lesinski52364f72016-01-11 13:10:24 -0800178 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
179 package="android">
Adam Lesinskicc5609d2016-04-05 12:41:07 -0700180 <application android:name=".MainApplication" text="hello">
181 <activity android:name=".activity.Start" />
182 <receiver android:name="com.google.android.Receiver" />
Adam Lesinski52364f72016-01-11 13:10:24 -0800183 </application>
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700184 </manifest>)EOF",
185 options);
186 ASSERT_NE(nullptr, doc);
Adam Lesinski52364f72016-01-11 13:10:24 -0800187
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700188 xml::Element* manifestEl = xml::findRootElement(doc.get());
189 ASSERT_NE(nullptr, manifestEl);
Adam Lesinski52364f72016-01-11 13:10:24 -0800190
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700191 xml::Attribute* attr = nullptr;
Adam Lesinski52364f72016-01-11 13:10:24 -0800192
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700193 attr = manifestEl->findAttribute({}, "package");
194 ASSERT_NE(nullptr, attr);
195 EXPECT_EQ(std::string("com.android"), attr->value);
Adam Lesinski52364f72016-01-11 13:10:24 -0800196
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700197 xml::Element* applicationEl = manifestEl->findChild({}, "application");
198 ASSERT_NE(nullptr, applicationEl);
Adam Lesinski52364f72016-01-11 13:10:24 -0800199
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700200 attr = applicationEl->findAttribute(xml::kSchemaAndroid, "name");
201 ASSERT_NE(nullptr, attr);
202 EXPECT_EQ(std::string("android.MainApplication"), attr->value);
Adam Lesinski52364f72016-01-11 13:10:24 -0800203
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700204 attr = applicationEl->findAttribute({}, "text");
205 ASSERT_NE(nullptr, attr);
206 EXPECT_EQ(std::string("hello"), attr->value);
Adam Lesinski52364f72016-01-11 13:10:24 -0800207
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700208 xml::Element* el;
209 el = applicationEl->findChild({}, "activity");
210 ASSERT_NE(nullptr, el);
Adam Lesinski52364f72016-01-11 13:10:24 -0800211
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700212 attr = el->findAttribute(xml::kSchemaAndroid, "name");
213 ASSERT_NE(nullptr, el);
214 EXPECT_EQ(std::string("android.activity.Start"), attr->value);
Adam Lesinski52364f72016-01-11 13:10:24 -0800215
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700216 el = applicationEl->findChild({}, "receiver");
217 ASSERT_NE(nullptr, el);
Adam Lesinski52364f72016-01-11 13:10:24 -0800218
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700219 attr = el->findAttribute(xml::kSchemaAndroid, "name");
220 ASSERT_NE(nullptr, el);
221 EXPECT_EQ(std::string("com.google.android.Receiver"), attr->value);
Adam Lesinski52364f72016-01-11 13:10:24 -0800222}
223
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700224TEST_F(ManifestFixerTest,
225 RenameManifestInstrumentationPackageAndFullyQualifyTarget) {
226 ManifestFixerOptions options;
227 options.renameInstrumentationTargetPackage = std::string("com.android");
Adam Lesinski52364f72016-01-11 13:10:24 -0800228
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700229 std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
Adam Lesinski52364f72016-01-11 13:10:24 -0800230 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
231 package="android">
232 <instrumentation android:targetPackage="android" />
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700233 </manifest>)EOF",
234 options);
235 ASSERT_NE(nullptr, doc);
Adam Lesinski52364f72016-01-11 13:10:24 -0800236
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700237 xml::Element* manifestEl = xml::findRootElement(doc.get());
238 ASSERT_NE(nullptr, manifestEl);
Adam Lesinski52364f72016-01-11 13:10:24 -0800239
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700240 xml::Element* instrumentationEl =
241 manifestEl->findChild({}, "instrumentation");
242 ASSERT_NE(nullptr, instrumentationEl);
Adam Lesinski52364f72016-01-11 13:10:24 -0800243
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700244 xml::Attribute* attr =
245 instrumentationEl->findAttribute(xml::kSchemaAndroid, "targetPackage");
246 ASSERT_NE(nullptr, attr);
247 EXPECT_EQ(std::string("com.android"), attr->value);
Adam Lesinski52364f72016-01-11 13:10:24 -0800248}
249
250TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700251 ManifestFixerOptions options;
252 options.versionNameDefault = std::string("Beta");
253 options.versionCodeDefault = std::string("0x10000000");
Adam Lesinski52364f72016-01-11 13:10:24 -0800254
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700255 std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF(
Adam Lesinski52364f72016-01-11 13:10:24 -0800256 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700257 package="android" />)EOF",
258 options);
259 ASSERT_NE(nullptr, doc);
Adam Lesinski52364f72016-01-11 13:10:24 -0800260
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700261 xml::Element* manifestEl = xml::findRootElement(doc.get());
262 ASSERT_NE(nullptr, manifestEl);
Adam Lesinski52364f72016-01-11 13:10:24 -0800263
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700264 xml::Attribute* attr =
265 manifestEl->findAttribute(xml::kSchemaAndroid, "versionName");
266 ASSERT_NE(nullptr, attr);
267 EXPECT_EQ(std::string("Beta"), attr->value);
Adam Lesinski52364f72016-01-11 13:10:24 -0800268
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700269 attr = manifestEl->findAttribute(xml::kSchemaAndroid, "versionCode");
270 ASSERT_NE(nullptr, attr);
271 EXPECT_EQ(std::string("0x10000000"), attr->value);
Adam Lesinski52364f72016-01-11 13:10:24 -0800272}
273
Adam Lesinski6b17d2c2016-08-10 11:37:06 -0700274TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700275 EXPECT_EQ(nullptr,
276 verify("<manifest package=\"android\" coreApp=\"hello\" />"));
277 EXPECT_EQ(nullptr,
278 verify("<manifest package=\"android\" coreApp=\"1dp\" />"));
Adam Lesinski6b17d2c2016-08-10 11:37:06 -0700279
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700280 std::unique_ptr<xml::XmlResource> doc =
281 verify("<manifest package=\"android\" coreApp=\"true\" />");
282 ASSERT_NE(nullptr, doc);
Adam Lesinski6b17d2c2016-08-10 11:37:06 -0700283
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700284 xml::Element* el = xml::findRootElement(doc.get());
285 ASSERT_NE(nullptr, el);
Adam Lesinski6b17d2c2016-08-10 11:37:06 -0700286
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700287 EXPECT_EQ("manifest", el->name);
Adam Lesinski6b17d2c2016-08-10 11:37:06 -0700288
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700289 xml::Attribute* attr = el->findAttribute("", "coreApp");
290 ASSERT_NE(nullptr, attr);
Adam Lesinski6b17d2c2016-08-10 11:37:06 -0700291
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700292 EXPECT_NE(nullptr, attr->compiledValue);
293 EXPECT_NE(nullptr, valueCast<BinaryPrimitive>(attr->compiledValue.get()));
Adam Lesinski6b17d2c2016-08-10 11:37:06 -0700294}
295
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700296} // namespace aapt