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
21 using ::android::StringPiece;
22 using ::testing::Eq;
23 using ::testing::Gt;
24 using ::testing::IsNull;
25 using ::testing::Ne;
26 using ::testing::NotNull;
27 using ::testing::StrEq;
28
29 namespace aapt {
30
31 struct ManifestFixerTest : public ::testing::Test {
32 std::unique_ptr<IAaptContext> mContext;
33
SetUpaapt::ManifestFixerTest34 void SetUp() override {
35 mContext =
36 test::ContextBuilder()
37 .SetCompilationPackage("android")
38 .SetPackageId(0x01)
39 .SetNameManglerPolicy(NameManglerPolicy{"android"})
40 .AddSymbolSource(
41 test::StaticSymbolSourceBuilder()
42 .AddSymbol(
43 "android:attr/package", ResourceId(0x01010000),
44 test::AttributeBuilder()
45 .SetTypeMask(android::ResTable_map::TYPE_STRING)
46 .Build())
47 .AddSymbol(
48 "android:attr/minSdkVersion", ResourceId(0x01010001),
49 test::AttributeBuilder()
50 .SetTypeMask(android::ResTable_map::TYPE_STRING |
51 android::ResTable_map::TYPE_INTEGER)
52 .Build())
53 .AddSymbol(
54 "android:attr/targetSdkVersion", ResourceId(0x01010002),
55 test::AttributeBuilder()
56 .SetTypeMask(android::ResTable_map::TYPE_STRING |
57 android::ResTable_map::TYPE_INTEGER)
58 .Build())
59 .AddSymbol("android:string/str", ResourceId(0x01060000))
60 .Build())
61 .Build();
62 }
63
Verifyaapt::ManifestFixerTest64 std::unique_ptr<xml::XmlResource> Verify(const StringPiece& str) {
65 return VerifyWithOptions(str, {});
66 }
67
VerifyWithOptionsaapt::ManifestFixerTest68 std::unique_ptr<xml::XmlResource> VerifyWithOptions(
69 const StringPiece& str, const ManifestFixerOptions& options) {
70 std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(str);
71 ManifestFixer fixer(options);
72 if (fixer.Consume(mContext.get(), doc.get())) {
73 return doc;
74 }
75 return {};
76 }
77 };
78
TEST_F(ManifestFixerTest,EnsureManifestIsRootTag)79 TEST_F(ManifestFixerTest, EnsureManifestIsRootTag) {
80 EXPECT_THAT(Verify("<other-tag />"), IsNull());
81 EXPECT_THAT(Verify("<ns:manifest xmlns:ns=\"com\" />"), IsNull());
82 EXPECT_THAT(Verify("<manifest package=\"android\"></manifest>"), NotNull());
83 }
84
TEST_F(ManifestFixerTest,EnsureManifestHasPackage)85 TEST_F(ManifestFixerTest, EnsureManifestHasPackage) {
86 EXPECT_THAT(Verify("<manifest package=\"android\" />"), NotNull());
87 EXPECT_THAT(Verify("<manifest package=\"com.android\" />"), NotNull());
88 EXPECT_THAT(Verify("<manifest package=\"com.android.google\" />"), NotNull());
89 EXPECT_THAT(Verify("<manifest package=\"com.android.google.Class$1\" />"), IsNull());
90 EXPECT_THAT(Verify("<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" "
91 "android:package=\"com.android\" />"),
92 IsNull());
93 EXPECT_THAT(Verify("<manifest package=\"@string/str\" />"), IsNull());
94 }
95
TEST_F(ManifestFixerTest,AllowMetaData)96 TEST_F(ManifestFixerTest, AllowMetaData) {
97 auto doc = Verify(R"EOF(
98 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
99 package="android">
100 <meta-data />
101 <application>
102 <meta-data />
103 <activity android:name=".Hi"><meta-data /></activity>
104 <activity-alias android:name=".Ho"><meta-data /></activity-alias>
105 <receiver android:name=".OffTo"><meta-data /></receiver>
106 <provider android:name=".Work"><meta-data /></provider>
107 <service android:name=".We"><meta-data /></service>
108 </application>
109 <instrumentation android:name=".Go"><meta-data /></instrumentation>
110 </manifest>)EOF");
111 ASSERT_THAT(doc, NotNull());
112 }
113
114 TEST_F(ManifestFixerTest, UseDefaultSdkVersionsIfNonePresent) {
115 ManifestFixerOptions options;
116 options.min_sdk_version_default = std::string("8");
117 options.target_sdk_version_default = std::string("22");
118
119 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
120 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
121 package="android">
122 <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="21" />
123 </manifest>)EOF",
124 options);
125 ASSERT_THAT(doc, NotNull());
126
127 xml::Element* el;
128 xml::Attribute* attr;
129
130 el = doc->root.get();
131 ASSERT_THAT(el, NotNull());
132 el = el->FindChild({}, "uses-sdk");
133 ASSERT_THAT(el, NotNull());
134 attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
135 ASSERT_THAT(attr, NotNull());
136 EXPECT_THAT(attr->value, StrEq("7"));
137 attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
138 ASSERT_THAT(attr, NotNull());
139 EXPECT_THAT(attr->value, StrEq("21"));
140
141 doc = VerifyWithOptions(R"EOF(
142 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
143 package="android">
144 <uses-sdk android:targetSdkVersion="21" />
145 </manifest>)EOF",
146 options);
147 ASSERT_THAT(doc, NotNull());
148
149 el = doc->root.get();
150 ASSERT_THAT(el, NotNull());
151 el = el->FindChild({}, "uses-sdk");
152 ASSERT_THAT(el, NotNull());
153 attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
154 ASSERT_THAT(attr, NotNull());
155 EXPECT_THAT(attr->value, StrEq("8"));
156 attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
157 ASSERT_THAT(attr, NotNull());
158 EXPECT_THAT(attr->value, StrEq("21"));
159
160 doc = VerifyWithOptions(R"EOF(
161 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
162 package="android">
163 <uses-sdk />
164 </manifest>)EOF",
165 options);
166 ASSERT_THAT(doc, NotNull());
167
168 el = doc->root.get();
169 ASSERT_THAT(el, NotNull());
170 el = el->FindChild({}, "uses-sdk");
171 ASSERT_THAT(el, NotNull());
172 attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
173 ASSERT_THAT(attr, NotNull());
174 EXPECT_THAT(attr->value, StrEq("8"));
175 attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
176 ASSERT_THAT(attr, NotNull());
177 EXPECT_THAT(attr->value, StrEq("22"));
178
179 doc = VerifyWithOptions(R"EOF(
180 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
181 package="android" />)EOF",
182 options);
183 ASSERT_THAT(doc, NotNull());
184
185 el = doc->root.get();
186 ASSERT_THAT(el, NotNull());
187 el = el->FindChild({}, "uses-sdk");
188 ASSERT_THAT(el, NotNull());
189 attr = el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion");
190 ASSERT_THAT(attr, NotNull());
191 EXPECT_THAT(attr->value, StrEq("8"));
192 attr = el->FindAttribute(xml::kSchemaAndroid, "targetSdkVersion");
193 ASSERT_THAT(attr, NotNull());
194 EXPECT_THAT(attr->value, StrEq("22"));
195 }
196
197 TEST_F(ManifestFixerTest, UsesSdkMustComeBeforeApplication) {
198 ManifestFixerOptions options;
199 options.min_sdk_version_default = std::string("8");
200 options.target_sdk_version_default = std::string("22");
201 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
202 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
203 package="android">
204 <application android:name=".MainApplication" />
205 </manifest>)EOF",
206 options);
207 ASSERT_THAT(doc, NotNull());
208
209 xml::Element* manifest_el = doc->root.get();
210 ASSERT_THAT(manifest_el, NotNull());
211 ASSERT_EQ("manifest", manifest_el->name);
212
213 xml::Element* application_el = manifest_el->FindChild("", "application");
214 ASSERT_THAT(application_el, NotNull());
215
216 xml::Element* uses_sdk_el = manifest_el->FindChild("", "uses-sdk");
217 ASSERT_THAT(uses_sdk_el, NotNull());
218
219 // Check that the uses_sdk_el comes before application_el in the children
220 // vector.
221 // Since there are no namespaces here, these children are direct descendants
222 // of manifest.
223 auto uses_sdk_iter =
224 std::find_if(manifest_el->children.begin(), manifest_el->children.end(),
225 [&](const std::unique_ptr<xml::Node>& child) {
226 return child.get() == uses_sdk_el;
227 });
228
229 auto application_iter =
230 std::find_if(manifest_el->children.begin(), manifest_el->children.end(),
231 [&](const std::unique_ptr<xml::Node>& child) {
232 return child.get() == application_el;
233 });
234
235 ASSERT_THAT(uses_sdk_iter, Ne(manifest_el->children.end()));
236 ASSERT_THAT(application_iter, Ne(manifest_el->children.end()));
237
238 // The distance should be positive, meaning uses_sdk_iter comes before
239 // application_iter.
240 EXPECT_THAT(std::distance(uses_sdk_iter, application_iter), Gt(0));
241 }
242
243 TEST_F(ManifestFixerTest, RenameManifestPackageAndFullyQualifyClasses) {
244 ManifestFixerOptions options;
245 options.rename_manifest_package = std::string("com.android");
246
247 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
248 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
249 package="android">
250 <uses-split android:name="feature_a" />
251 <application android:name=".MainApplication" text="hello">
252 <activity android:name=".activity.Start" />
253 <receiver android:name="com.google.android.Receiver" />
254 </application>
255 </manifest>)EOF",
256 options);
257 ASSERT_THAT(doc, NotNull());
258
259 xml::Element* manifest_el = doc->root.get();
260 ASSERT_THAT(manifest_el, NotNull());
261
262 xml::Attribute* attr = nullptr;
263
264 attr = manifest_el->FindAttribute({}, "package");
265 ASSERT_THAT(attr, NotNull());
266 EXPECT_THAT(attr->value, StrEq("com.android"));
267
268 xml::Element* uses_split_el = manifest_el->FindChild({}, "uses-split");
269 ASSERT_THAT(uses_split_el, NotNull());
270 attr = uses_split_el->FindAttribute(xml::kSchemaAndroid, "name");
271 ASSERT_THAT(attr, NotNull());
272 // This should NOT have been affected.
273 EXPECT_THAT(attr->value, StrEq("feature_a"));
274
275 xml::Element* application_el = manifest_el->FindChild({}, "application");
276 ASSERT_THAT(application_el, NotNull());
277
278 attr = application_el->FindAttribute(xml::kSchemaAndroid, "name");
279 ASSERT_THAT(attr, NotNull());
280 EXPECT_THAT(attr->value, StrEq("android.MainApplication"));
281
282 attr = application_el->FindAttribute({}, "text");
283 ASSERT_THAT(attr, NotNull());
284 EXPECT_THAT(attr->value, StrEq("hello"));
285
286 xml::Element* el;
287 el = application_el->FindChild({}, "activity");
288 ASSERT_THAT(el, NotNull());
289
290 attr = el->FindAttribute(xml::kSchemaAndroid, "name");
291 ASSERT_THAT(el, NotNull());
292 EXPECT_THAT(attr->value, StrEq("android.activity.Start"));
293
294 el = application_el->FindChild({}, "receiver");
295 ASSERT_THAT(el, NotNull());
296
297 attr = el->FindAttribute(xml::kSchemaAndroid, "name");
298 ASSERT_THAT(el, NotNull());
299 EXPECT_THAT(attr->value, StrEq("com.google.android.Receiver"));
300 }
301
302 TEST_F(ManifestFixerTest,
303 RenameManifestInstrumentationPackageAndFullyQualifyTarget) {
304 ManifestFixerOptions options;
305 options.rename_instrumentation_target_package = std::string("com.android");
306
307 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
308 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
309 package="android">
310 <instrumentation android:name=".TestRunner" android:targetPackage="android" />
311 </manifest>)EOF",
312 options);
313 ASSERT_THAT(doc, NotNull());
314
315 xml::Element* manifest_el = doc->root.get();
316 ASSERT_THAT(manifest_el, NotNull());
317
318 xml::Element* instrumentation_el =
319 manifest_el->FindChild({}, "instrumentation");
320 ASSERT_THAT(instrumentation_el, NotNull());
321
322 xml::Attribute* attr =
323 instrumentation_el->FindAttribute(xml::kSchemaAndroid, "targetPackage");
324 ASSERT_THAT(attr, NotNull());
325 EXPECT_THAT(attr->value, StrEq("com.android"));
326 }
327
328 TEST_F(ManifestFixerTest,
329 RenameManifestOverlayPackageAndFullyQualifyTarget) {
330 ManifestFixerOptions options;
331 options.rename_overlay_target_package = std::string("com.android");
332
333 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
334 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
335 package="android">
336 <overlay android:targetName="Customization" android:targetPackage="android" />
337 </manifest>)EOF",
338 options);
339 ASSERT_THAT(doc, NotNull());
340
341 xml::Element* manifest_el = doc->root.get();
342 ASSERT_THAT(manifest_el, NotNull());
343
344 xml::Element* overlay_el =
345 manifest_el->FindChild({}, "overlay");
346 ASSERT_THAT(overlay_el, NotNull());
347
348 xml::Attribute* attr =
349 overlay_el->FindAttribute(xml::kSchemaAndroid, "targetPackage");
350 ASSERT_THAT(attr, NotNull());
351 EXPECT_THAT(attr->value, StrEq("com.android"));
352 }
353
354 TEST_F(ManifestFixerTest, UseDefaultVersionNameAndCode) {
355 ManifestFixerOptions options;
356 options.version_name_default = std::string("Beta");
357 options.version_code_default = std::string("0x10000000");
358 options.version_code_major_default = std::string("0x20000000");
359
360 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
361 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
362 package="android" />)EOF",
363 options);
364 ASSERT_THAT(doc, NotNull());
365
366 xml::Element* manifest_el = doc->root.get();
367 ASSERT_THAT(manifest_el, NotNull());
368
369 xml::Attribute* attr =
370 manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
371 ASSERT_THAT(attr, NotNull());
372 EXPECT_THAT(attr->value, StrEq("Beta"));
373
374 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
375 ASSERT_THAT(attr, NotNull());
376 EXPECT_THAT(attr->value, StrEq("0x10000000"));
377
378 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
379 ASSERT_THAT(attr, NotNull());
380 EXPECT_THAT(attr->value, StrEq("0x20000000"));
381 }
382
383 TEST_F(ManifestFixerTest, DontUseDefaultVersionNameAndCode) {
384 ManifestFixerOptions options;
385 options.version_name_default = std::string("Beta");
386 options.version_code_default = std::string("0x10000000");
387 options.version_code_major_default = std::string("0x20000000");
388
389 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
390 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
391 package="android"
392 android:versionCode="0x00000001"
393 android:versionCodeMajor="0x00000002"
394 android:versionName="Alpha" />)EOF",
395 options);
396 ASSERT_THAT(doc, NotNull());
397
398 xml::Element* manifest_el = doc->root.get();
399 ASSERT_THAT(manifest_el, NotNull());
400
401 xml::Attribute* attr =
402 manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
403 ASSERT_THAT(attr, NotNull());
404 EXPECT_THAT(attr->value, StrEq("Alpha"));
405
406 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
407 ASSERT_THAT(attr, NotNull());
408 EXPECT_THAT(attr->value, StrEq("0x00000001"));
409
410 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
411 ASSERT_THAT(attr, NotNull());
412 EXPECT_THAT(attr->value, StrEq("0x00000002"));
413 }
414
415 TEST_F(ManifestFixerTest, ReplaceVersionNameAndCode) {
416 ManifestFixerOptions options;
417 options.replace_version = true;
418 options.version_name_default = std::string("Beta");
419 options.version_code_default = std::string("0x10000000");
420 options.version_code_major_default = std::string("0x20000000");
421
422 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
423 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
424 package="android"
425 android:versionCode="0x00000001"
426 android:versionCodeMajor="0x00000002"
427 android:versionName="Alpha" />)EOF",
428 options);
429 ASSERT_THAT(doc, NotNull());
430
431 xml::Element* manifest_el = doc->root.get();
432 ASSERT_THAT(manifest_el, NotNull());
433
434 xml::Attribute* attr =
435 manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
436 ASSERT_THAT(attr, NotNull());
437 EXPECT_THAT(attr->value, StrEq("Beta"));
438
439 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
440 ASSERT_THAT(attr, NotNull());
441 EXPECT_THAT(attr->value, StrEq("0x10000000"));
442
443 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
444 ASSERT_THAT(attr, NotNull());
445 EXPECT_THAT(attr->value, StrEq("0x20000000"));
446 }
447
448 TEST_F(ManifestFixerTest, UseDefaultRevisionCode) {
449 ManifestFixerOptions options;
450 options.revision_code_default = std::string("0x10000000");
451
452 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
453 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
454 package="android"
455 android:versionCode="0x00000001" />)EOF",
456 options);
457 ASSERT_THAT(doc, NotNull());
458
459 xml::Element* manifest_el = doc->root.get();
460 ASSERT_THAT(manifest_el, NotNull());
461
462 xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode");
463 ASSERT_THAT(attr, NotNull());
464 EXPECT_THAT(attr->value, StrEq("0x10000000"));
465 }
466
467 TEST_F(ManifestFixerTest, DontUseDefaultRevisionCode) {
468 ManifestFixerOptions options;
469 options.revision_code_default = std::string("0x10000000");
470
471 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
472 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
473 package="android"
474 android:versionCode="0x00000001"
475 android:revisionCode="0x00000002" />)EOF",
476 options);
477 ASSERT_THAT(doc, NotNull());
478
479 xml::Element* manifest_el = doc->root.get();
480 ASSERT_THAT(manifest_el, NotNull());
481
482 xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode");
483 ASSERT_THAT(attr, NotNull());
484 EXPECT_THAT(attr->value, StrEq("0x00000002"));
485 }
486
487 TEST_F(ManifestFixerTest, ReplaceRevisionCode) {
488 ManifestFixerOptions options;
489 options.replace_version = true;
490 options.revision_code_default = std::string("0x10000000");
491
492 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
493 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
494 package="android"
495 android:versionCode="0x00000001"
496 android:revisionCode="0x00000002" />)EOF",
497 options);
498 ASSERT_THAT(doc, NotNull());
499
500 xml::Element* manifest_el = doc->root.get();
501 ASSERT_THAT(manifest_el, NotNull());
502
503 xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode");
504 ASSERT_THAT(attr, NotNull());
505 EXPECT_THAT(attr->value, StrEq("0x10000000"));
506 }
507
508 TEST_F(ManifestFixerTest, ReplaceVersionName) {
509 ManifestFixerOptions options;
510 options.replace_version = true;
511 options.version_name_default = std::string("Beta");
512
513
514 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
515 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
516 package="android"
517 android:versionCode="0x00000001"
518 android:versionCodeMajor="0x00000002"
519 android:versionName="Alpha" />)EOF",
520 options);
521 ASSERT_THAT(doc, NotNull());
522
523 xml::Element* manifest_el = doc->root.get();
524 ASSERT_THAT(manifest_el, NotNull());
525
526 xml::Attribute* attr =
527 manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
528 ASSERT_THAT(attr, NotNull());
529 EXPECT_THAT(attr->value, StrEq("Beta"));
530
531 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
532 ASSERT_THAT(attr, NotNull());
533 EXPECT_THAT(attr->value, StrEq("0x00000001"));
534
535 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
536 ASSERT_THAT(attr, NotNull());
537 EXPECT_THAT(attr->value, StrEq("0x00000002"));
538 }
539
540 TEST_F(ManifestFixerTest, ReplaceVersionCode) {
541 ManifestFixerOptions options;
542 options.replace_version = true;
543 options.version_code_default = std::string("0x10000000");
544
545 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
546 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
547 package="android"
548 android:versionCode="0x00000001"
549 android:versionCodeMajor="0x00000002"
550 android:versionName="Alpha" />)EOF",
551 options);
552 ASSERT_THAT(doc, NotNull());
553
554 xml::Element* manifest_el = doc->root.get();
555 ASSERT_THAT(manifest_el, NotNull());
556
557 xml::Attribute* attr =
558 manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
559 ASSERT_THAT(attr, NotNull());
560 EXPECT_THAT(attr->value, StrEq("Alpha"));
561
562 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
563 ASSERT_THAT(attr, NotNull());
564 EXPECT_THAT(attr->value, StrEq("0x10000000"));
565
566 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
567 ASSERT_THAT(attr, NotNull());
568 EXPECT_THAT(attr->value, StrEq("0x00000002"));
569 }
570
571 TEST_F(ManifestFixerTest, ReplaceVersionCodeMajor) {
572 ManifestFixerOptions options;
573 options.replace_version = true;
574 options.version_code_major_default = std::string("0x20000000");
575
576 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
577 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
578 package="android"
579 android:versionCode="0x00000001"
580 android:versionCodeMajor="0x00000002"
581 android:versionName="Alpha" />)EOF",
582 options);
583 ASSERT_THAT(doc, NotNull());
584
585 xml::Element* manifest_el = doc->root.get();
586 ASSERT_THAT(manifest_el, NotNull());
587
588 xml::Attribute* attr =
589 manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
590 ASSERT_THAT(attr, NotNull());
591 EXPECT_THAT(attr->value, StrEq("Alpha"));
592
593 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
594 ASSERT_THAT(attr, NotNull());
595 EXPECT_THAT(attr->value, StrEq("0x00000001"));
596
597 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
598 ASSERT_THAT(attr, NotNull());
599 EXPECT_THAT(attr->value, StrEq("0x20000000"));
600 }
601
602 TEST_F(ManifestFixerTest, DontReplaceVersionNameOrCode) {
603 ManifestFixerOptions options;
604 options.replace_version = true;
605
606 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
607 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
608 package="android"
609 android:versionCode="0x00000001"
610 android:versionCodeMajor="0x00000002"
611 android:versionName="Alpha" />)EOF",
612 options);
613 ASSERT_THAT(doc, NotNull());
614
615 xml::Element* manifest_el = doc->root.get();
616 ASSERT_THAT(manifest_el, NotNull());
617
618 xml::Attribute* attr =
619 manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
620 ASSERT_THAT(attr, NotNull());
621 EXPECT_THAT(attr->value, StrEq("Alpha"));
622
623 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
624 ASSERT_THAT(attr, NotNull());
625 EXPECT_THAT(attr->value, StrEq("0x00000001"));
626
627 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
628 ASSERT_THAT(attr, NotNull());
629 EXPECT_THAT(attr->value, StrEq("0x00000002"));
630 }
631
632 TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) {
633 EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"hello\" />"), IsNull());
634 EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"1dp\" />"), IsNull());
635
636 std::unique_ptr<xml::XmlResource> doc =
637 Verify("<manifest package=\"android\" coreApp=\"true\" />");
638 ASSERT_THAT(doc, NotNull());
639
640 xml::Element* el = doc->root.get();
641 ASSERT_THAT(el, NotNull());
642
643 EXPECT_THAT(el->name, StrEq("manifest"));
644
645 xml::Attribute* attr = el->FindAttribute("", "coreApp");
646 ASSERT_THAT(attr, NotNull());
647
648 EXPECT_THAT(attr->compiled_value, NotNull());
649 EXPECT_THAT(ValueCast<BinaryPrimitive>(attr->compiled_value.get()), NotNull());
650 }
651
TEST_F(ManifestFixerTest,UsesFeatureMustHaveNameOrGlEsVersion)652 TEST_F(ManifestFixerTest, UsesFeatureMustHaveNameOrGlEsVersion) {
653 std::string input = R"EOF(
654 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
655 package="android">
656 <uses-feature android:name="feature" />
657 <uses-feature android:glEsVersion="1" />
658 <feature-group />
659 <feature-group>
660 <uses-feature android:name="feature_in_group" />
661 <uses-feature android:glEsVersion="2" />
662 </feature-group>
663 </manifest>)EOF";
664 EXPECT_THAT(Verify(input), NotNull());
665
666 input = R"EOF(
667 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
668 package="android">
669 <uses-feature android:name="feature" android:glEsVersion="1" />
670 </manifest>)EOF";
671 EXPECT_THAT(Verify(input), IsNull());
672
673 input = R"EOF(
674 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
675 package="android">
676 <uses-feature />
677 </manifest>)EOF";
678 EXPECT_THAT(Verify(input), IsNull());
679
680 input = R"EOF(
681 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
682 package="android">
683 <feature-group>
684 <uses-feature android:name="feature" android:glEsVersion="1" />
685 </feature-group>
686 </manifest>)EOF";
687 EXPECT_THAT(Verify(input), IsNull());
688
689 input = R"EOF(
690 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
691 package="android">
692 <feature-group>
693 <uses-feature />
694 </feature-group>
695 </manifest>)EOF";
696 EXPECT_THAT(Verify(input), IsNull());
697 }
698
699 TEST_F(ManifestFixerTest, ApplicationInjectDebuggable) {
700 ManifestFixerOptions options;
701 options.debug_mode = true;
702
703 std::string no_d = R"(
704 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
705 package="android">
706 <application>
707 </application>
708 </manifest>)";
709
710 std::string false_d = R"(
711 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
712 package="android">
713 <application android:debuggable="false">
714 </application>
715 </manifest>)";
716
717 std::string true_d = R"(
718 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
719 package="android">
720 <application android:debuggable="true">
721 </application>
722 </manifest>)";
723
724 // Inject the debuggable attribute when the attribute is not present and the
725 // flag is present
726 std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(no_d, options);
727 EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
728 {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
729
730 // Set the debuggable flag to true if the attribute is false and the flag is
731 // present
732 manifest = VerifyWithOptions(false_d, options);
733 EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
734 {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
735
736 // Keep debuggable flag true if the attribute is true and the flag is present
737 manifest = VerifyWithOptions(true_d, options);
738 EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
739 {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
740
741 // Do not inject the debuggable attribute when the attribute is not present
742 // and the flag is not present
743 manifest = Verify(no_d);
744 EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
745 {}, "application", xml::kSchemaAndroid, "debuggable", "true"), IsNull());
746
747 // Do not set the debuggable flag to true if the attribute is false and the
748 // flag is not present
749 manifest = Verify(false_d);
750 EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
751 {}, "application", xml::kSchemaAndroid, "debuggable", "true"), IsNull());
752
753 // Keep debuggable flag true if the attribute is true and the flag is not
754 // present
755 manifest = Verify(true_d);
756 EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
757 {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
758 }
759
760 TEST_F(ManifestFixerTest, ApplicationProfileable) {
761 std::string shell = R"(
762 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
763 package="android">
764 <application>
765 <profileable android:shell="true"/>
766 </application>
767 </manifest>)";
768 EXPECT_THAT(Verify(shell), NotNull());
769 std::string noshell = R"(
770 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
771 package="android">
772 <application>
773 <profileable/>
774 </application>
775 </manifest>)";
776 EXPECT_THAT(Verify(noshell), NotNull());
777 }
778
779 TEST_F(ManifestFixerTest, IgnoreNamespacedElements) {
780 std::string input = R"EOF(
781 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
782 package="android">
783 <special:tag whoo="true" xmlns:special="http://google.com" />
784 </manifest>)EOF";
785 EXPECT_THAT(Verify(input), NotNull());
786 }
787
788 TEST_F(ManifestFixerTest, DoNotIgnoreNonNamespacedElements) {
789 std::string input = R"EOF(
790 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
791 package="android">
792 <tag whoo="true" />
793 </manifest>)EOF";
794 EXPECT_THAT(Verify(input), IsNull());
795 }
796
797 TEST_F(ManifestFixerTest, SupportKeySets) {
798 std::string input = R"(
799 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
800 package="android">
801 <key-sets>
802 <key-set android:name="old-set">
803 <public-key android:name="old-key" android:value="some+old+key" />
804 </key-set>
805 <key-set android:name="new-set">
806 <public-key android:name="new-key" android:value="some+new+key" />
807 </key-set>
808 <upgrade-key-set android:name="old-set" />
809 <upgrade-key-set android:name="new-set" />
810 </key-sets>
811 </manifest>)";
812 EXPECT_THAT(Verify(input), NotNull());
813 }
814
815 TEST_F(ManifestFixerTest, InsertCompileSdkVersions) {
816 std::string input = R"(<manifest package="com.pkg" />)";
817 ManifestFixerOptions options;
818 options.compile_sdk_version = {"28"};
819 options.compile_sdk_version_codename = {"P"};
820
821 std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options);
822 ASSERT_THAT(manifest, NotNull());
823
824 // There should be a declaration of kSchemaAndroid, even when the input
825 // didn't have one.
826 EXPECT_EQ(manifest->root->namespace_decls.size(), 1);
827 EXPECT_EQ(manifest->root->namespace_decls[0].prefix, "android");
828 EXPECT_EQ(manifest->root->namespace_decls[0].uri, xml::kSchemaAndroid);
829
830 xml::Attribute* attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersion");
831 ASSERT_THAT(attr, NotNull());
832 EXPECT_THAT(attr->value, StrEq("28"));
833
834 attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersionCodename");
835 ASSERT_THAT(attr, NotNull());
836 EXPECT_THAT(attr->value, StrEq("P"));
837
838 attr = manifest->root->FindAttribute("", "platformBuildVersionCode");
839 ASSERT_THAT(attr, NotNull());
840 EXPECT_THAT(attr->value, StrEq("28"));
841
842 attr = manifest->root->FindAttribute("", "platformBuildVersionName");
843 ASSERT_THAT(attr, NotNull());
844 EXPECT_THAT(attr->value, StrEq("P"));
845 }
846
847 TEST_F(ManifestFixerTest, OverrideCompileSdkVersions) {
848 std::string input = R"(
849 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"
850 compileSdkVersion="27" compileSdkVersionCodename="O"
851 platformBuildVersionCode="27" platformBuildVersionName="O"/>)";
852 ManifestFixerOptions options;
853 options.compile_sdk_version = {"28"};
854 options.compile_sdk_version_codename = {"P"};
855
856 std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options);
857 ASSERT_THAT(manifest, NotNull());
858
859 xml::Attribute* attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersion");
860 ASSERT_THAT(attr, NotNull());
861 EXPECT_THAT(attr->value, StrEq("28"));
862
863 attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersionCodename");
864 ASSERT_THAT(attr, NotNull());
865 EXPECT_THAT(attr->value, StrEq("P"));
866
867 attr = manifest->root->FindAttribute("", "platformBuildVersionCode");
868 ASSERT_THAT(attr, NotNull());
869 EXPECT_THAT(attr->value, StrEq("28"));
870
871 attr = manifest->root->FindAttribute("", "platformBuildVersionName");
872 ASSERT_THAT(attr, NotNull());
873 EXPECT_THAT(attr->value, StrEq("P"));
874 }
875
876 TEST_F(ManifestFixerTest, AndroidPrefixAlreadyUsed) {
877 std::string input =
878 R"(<manifest package="com.pkg"
879 xmlns:android="http://schemas.android.com/apk/prv/res/android"
880 android:private_attr="foo" />)";
881 ManifestFixerOptions options;
882 options.compile_sdk_version = {"28"};
883 options.compile_sdk_version_codename = {"P"};
884
885 std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options);
886 ASSERT_THAT(manifest, NotNull());
887
888 // Make sure that we don't redefine "android".
889 EXPECT_EQ(manifest->root->namespace_decls.size(), 2);
890 EXPECT_EQ(manifest->root->namespace_decls[0].prefix, "android");
891 EXPECT_EQ(manifest->root->namespace_decls[0].uri,
892 "http://schemas.android.com/apk/prv/res/android");
893 EXPECT_EQ(manifest->root->namespace_decls[1].prefix, "android0");
894 EXPECT_EQ(manifest->root->namespace_decls[1].uri, xml::kSchemaAndroid);
895 }
896
TEST_F(ManifestFixerTest,UnexpectedElementsInManifest)897 TEST_F(ManifestFixerTest, UnexpectedElementsInManifest) {
898 std::string input = R"(
899 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
900 package="android">
901 <beep/>
902 </manifest>)";
903 ManifestFixerOptions options;
904 options.warn_validation = true;
905
906 // Unexpected element should result in a warning if the flag is set to 'true'.
907 std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options);
908 ASSERT_THAT(manifest, NotNull());
909
910 // Unexpected element should result in an error if the flag is set to 'false'.
911 options.warn_validation = false;
912 manifest = VerifyWithOptions(input, options);
913 ASSERT_THAT(manifest, IsNull());
914
915 // By default the flag should be set to 'false'.
916 manifest = Verify(input);
917 ASSERT_THAT(manifest, IsNull());
918 }
919
920 TEST_F(ManifestFixerTest, UsesLibraryMustHaveNonEmptyName) {
921 std::string input = R"(
922 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
923 package="android">
924 <application>
925 <uses-library android:name="" />
926 </application>
927 </manifest>)";
928 EXPECT_THAT(Verify(input), IsNull());
929
930 input = R"(
931 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
932 package="android">
933 <application>
934 <uses-library />
935 </application>
936 </manifest>)";
937 EXPECT_THAT(Verify(input), IsNull());
938
939 input = R"(
940 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
941 package="android">
942 <application>
943 <uses-library android:name="blahhh" />
944 </application>
945 </manifest>)";
946 EXPECT_THAT(Verify(input), NotNull());
947 }
948
949 TEST_F(ManifestFixerTest, ApplicationPropertyAttributeRequired) {
950 std::string input = R"(
951 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
952 package="android">
953 <application>
954 <property android:name="" />
955 </application>
956 </manifest>)";
957 EXPECT_THAT(Verify(input), IsNull());
958 }
959
960 TEST_F(ManifestFixerTest, ApplicationPropertyOnlyOneAttributeDefined) {
961 std::string input = R"(
962 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
963 package="android">
964 <application>
965 <property android:name="" android:value="" android:resource="" />
966 </application>
967 </manifest>)";
968 EXPECT_THAT(Verify(input), IsNull());
969
970 input = R"(
971 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
972 package="android">
973 <application>
974 <property android:name="" android:resource="" />
975 </application>
976 </manifest>)";
977 EXPECT_THAT(Verify(input), NotNull());
978
979 input = R"(
980 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
981 package="android">
982 <application>
983 <property android:name="" android:value="" />
984 </application>
985 </manifest>)";
986 EXPECT_THAT(Verify(input), NotNull());
987 }
988
989 TEST_F(ManifestFixerTest, ComponentPropertyOnlyOneAttributeDefined) {
990 std::string input = R"(
991 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
992 package="android">
993 <application>
994 <activity android:name=".MyActivity">
995 <property android:name="" android:value="" android:resource="" />
996 </activity>
997 </application>
998 </manifest>)";
999 EXPECT_THAT(Verify(input), IsNull());
1000
1001 input = R"(
1002 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
1003 package="android">
1004 <application>
1005 <activity android:name=".MyActivity">
1006 <property android:name="" android:value="" />
1007 </activity>
1008 </application>
1009 </manifest>)";
1010 EXPECT_THAT(Verify(input), NotNull());
1011
1012 input = R"(
1013 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
1014 package="android">
1015 <application>
1016 <activity android:name=".MyActivity">
1017 <property android:name="" android:resource="" />
1018 </activity>
1019 </application>
1020 </manifest>)";
1021 EXPECT_THAT(Verify(input), NotNull());
1022 }
1023 } // namespace aapt
1024