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 34 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 64 std::unique_ptr<xml::XmlResource> Verify(const StringPiece& str) { 65 return VerifyWithOptions(str, {}); 66 } 67 68 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 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 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 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, UseDefaultVersionNameAndCode) { 329 ManifestFixerOptions options; 330 options.version_name_default = std::string("Beta"); 331 options.version_code_default = std::string("0x10000000"); 332 options.version_code_major_default = std::string("0x20000000"); 333 334 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( 335 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 336 package="android" />)EOF", 337 options); 338 ASSERT_THAT(doc, NotNull()); 339 340 xml::Element* manifest_el = doc->root.get(); 341 ASSERT_THAT(manifest_el, NotNull()); 342 343 xml::Attribute* attr = 344 manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); 345 ASSERT_THAT(attr, NotNull()); 346 EXPECT_THAT(attr->value, StrEq("Beta")); 347 348 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); 349 ASSERT_THAT(attr, NotNull()); 350 EXPECT_THAT(attr->value, StrEq("0x10000000")); 351 352 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor"); 353 ASSERT_THAT(attr, NotNull()); 354 EXPECT_THAT(attr->value, StrEq("0x20000000")); 355 } 356 357 TEST_F(ManifestFixerTest, DontUseDefaultVersionNameAndCode) { 358 ManifestFixerOptions options; 359 options.version_name_default = std::string("Beta"); 360 options.version_code_default = std::string("0x10000000"); 361 options.version_code_major_default = std::string("0x20000000"); 362 363 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( 364 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 365 package="android" 366 android:versionCode="0x00000001" 367 android:versionCodeMajor="0x00000002" 368 android:versionName="Alpha" />)EOF", 369 options); 370 ASSERT_THAT(doc, NotNull()); 371 372 xml::Element* manifest_el = doc->root.get(); 373 ASSERT_THAT(manifest_el, NotNull()); 374 375 xml::Attribute* attr = 376 manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); 377 ASSERT_THAT(attr, NotNull()); 378 EXPECT_THAT(attr->value, StrEq("Alpha")); 379 380 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); 381 ASSERT_THAT(attr, NotNull()); 382 EXPECT_THAT(attr->value, StrEq("0x00000001")); 383 384 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor"); 385 ASSERT_THAT(attr, NotNull()); 386 EXPECT_THAT(attr->value, StrEq("0x00000002")); 387 } 388 389 TEST_F(ManifestFixerTest, ReplaceVersionNameAndCode) { 390 ManifestFixerOptions options; 391 options.replace_version = true; 392 options.version_name_default = std::string("Beta"); 393 options.version_code_default = std::string("0x10000000"); 394 options.version_code_major_default = std::string("0x20000000"); 395 396 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( 397 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 398 package="android" 399 android:versionCode="0x00000001" 400 android:versionCodeMajor="0x00000002" 401 android:versionName="Alpha" />)EOF", 402 options); 403 ASSERT_THAT(doc, NotNull()); 404 405 xml::Element* manifest_el = doc->root.get(); 406 ASSERT_THAT(manifest_el, NotNull()); 407 408 xml::Attribute* attr = 409 manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); 410 ASSERT_THAT(attr, NotNull()); 411 EXPECT_THAT(attr->value, StrEq("Beta")); 412 413 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); 414 ASSERT_THAT(attr, NotNull()); 415 EXPECT_THAT(attr->value, StrEq("0x10000000")); 416 417 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor"); 418 ASSERT_THAT(attr, NotNull()); 419 EXPECT_THAT(attr->value, StrEq("0x20000000")); 420 } 421 422 TEST_F(ManifestFixerTest, ReplaceVersionName) { 423 ManifestFixerOptions options; 424 options.replace_version = true; 425 options.version_name_default = std::string("Beta"); 426 427 428 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( 429 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 430 package="android" 431 android:versionCode="0x00000001" 432 android:versionCodeMajor="0x00000002" 433 android:versionName="Alpha" />)EOF", 434 options); 435 ASSERT_THAT(doc, NotNull()); 436 437 xml::Element* manifest_el = doc->root.get(); 438 ASSERT_THAT(manifest_el, NotNull()); 439 440 xml::Attribute* attr = 441 manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); 442 ASSERT_THAT(attr, NotNull()); 443 EXPECT_THAT(attr->value, StrEq("Beta")); 444 445 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); 446 ASSERT_THAT(attr, NotNull()); 447 EXPECT_THAT(attr->value, StrEq("0x00000001")); 448 449 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor"); 450 ASSERT_THAT(attr, NotNull()); 451 EXPECT_THAT(attr->value, StrEq("0x00000002")); 452 } 453 454 TEST_F(ManifestFixerTest, ReplaceVersionCode) { 455 ManifestFixerOptions options; 456 options.replace_version = true; 457 options.version_code_default = std::string("0x10000000"); 458 459 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( 460 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 461 package="android" 462 android:versionCode="0x00000001" 463 android:versionCodeMajor="0x00000002" 464 android:versionName="Alpha" />)EOF", 465 options); 466 ASSERT_THAT(doc, NotNull()); 467 468 xml::Element* manifest_el = doc->root.get(); 469 ASSERT_THAT(manifest_el, NotNull()); 470 471 xml::Attribute* attr = 472 manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); 473 ASSERT_THAT(attr, NotNull()); 474 EXPECT_THAT(attr->value, StrEq("Alpha")); 475 476 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); 477 ASSERT_THAT(attr, NotNull()); 478 EXPECT_THAT(attr->value, StrEq("0x10000000")); 479 480 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor"); 481 ASSERT_THAT(attr, NotNull()); 482 EXPECT_THAT(attr->value, StrEq("0x00000002")); 483 } 484 485 TEST_F(ManifestFixerTest, ReplaceVersionCodeMajor) { 486 ManifestFixerOptions options; 487 options.replace_version = true; 488 options.version_code_major_default = std::string("0x20000000"); 489 490 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( 491 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 492 package="android" 493 android:versionCode="0x00000001" 494 android:versionCodeMajor="0x00000002" 495 android:versionName="Alpha" />)EOF", 496 options); 497 ASSERT_THAT(doc, NotNull()); 498 499 xml::Element* manifest_el = doc->root.get(); 500 ASSERT_THAT(manifest_el, NotNull()); 501 502 xml::Attribute* attr = 503 manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); 504 ASSERT_THAT(attr, NotNull()); 505 EXPECT_THAT(attr->value, StrEq("Alpha")); 506 507 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); 508 ASSERT_THAT(attr, NotNull()); 509 EXPECT_THAT(attr->value, StrEq("0x00000001")); 510 511 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor"); 512 ASSERT_THAT(attr, NotNull()); 513 EXPECT_THAT(attr->value, StrEq("0x20000000")); 514 } 515 516 TEST_F(ManifestFixerTest, DontReplaceVersionNameOrCode) { 517 ManifestFixerOptions options; 518 options.replace_version = true; 519 520 std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF( 521 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 522 package="android" 523 android:versionCode="0x00000001" 524 android:versionCodeMajor="0x00000002" 525 android:versionName="Alpha" />)EOF", 526 options); 527 ASSERT_THAT(doc, NotNull()); 528 529 xml::Element* manifest_el = doc->root.get(); 530 ASSERT_THAT(manifest_el, NotNull()); 531 532 xml::Attribute* attr = 533 manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName"); 534 ASSERT_THAT(attr, NotNull()); 535 EXPECT_THAT(attr->value, StrEq("Alpha")); 536 537 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode"); 538 ASSERT_THAT(attr, NotNull()); 539 EXPECT_THAT(attr->value, StrEq("0x00000001")); 540 541 attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor"); 542 ASSERT_THAT(attr, NotNull()); 543 EXPECT_THAT(attr->value, StrEq("0x00000002")); 544 } 545 546 TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) { 547 EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"hello\" />"), IsNull()); 548 EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"1dp\" />"), IsNull()); 549 550 std::unique_ptr<xml::XmlResource> doc = 551 Verify("<manifest package=\"android\" coreApp=\"true\" />"); 552 ASSERT_THAT(doc, NotNull()); 553 554 xml::Element* el = doc->root.get(); 555 ASSERT_THAT(el, NotNull()); 556 557 EXPECT_THAT(el->name, StrEq("manifest")); 558 559 xml::Attribute* attr = el->FindAttribute("", "coreApp"); 560 ASSERT_THAT(attr, NotNull()); 561 562 EXPECT_THAT(attr->compiled_value, NotNull()); 563 EXPECT_THAT(ValueCast<BinaryPrimitive>(attr->compiled_value.get()), NotNull()); 564 } 565 566 TEST_F(ManifestFixerTest, UsesFeatureMustHaveNameOrGlEsVersion) { 567 std::string input = R"EOF( 568 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 569 package="android"> 570 <uses-feature android:name="feature" /> 571 <uses-feature android:glEsVersion="1" /> 572 <feature-group /> 573 <feature-group> 574 <uses-feature android:name="feature_in_group" /> 575 <uses-feature android:glEsVersion="2" /> 576 </feature-group> 577 </manifest>)EOF"; 578 EXPECT_THAT(Verify(input), NotNull()); 579 580 input = R"EOF( 581 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 582 package="android"> 583 <uses-feature android:name="feature" android:glEsVersion="1" /> 584 </manifest>)EOF"; 585 EXPECT_THAT(Verify(input), IsNull()); 586 587 input = R"EOF( 588 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 589 package="android"> 590 <uses-feature /> 591 </manifest>)EOF"; 592 EXPECT_THAT(Verify(input), IsNull()); 593 594 input = R"EOF( 595 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 596 package="android"> 597 <feature-group> 598 <uses-feature android:name="feature" android:glEsVersion="1" /> 599 </feature-group> 600 </manifest>)EOF"; 601 EXPECT_THAT(Verify(input), IsNull()); 602 603 input = R"EOF( 604 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 605 package="android"> 606 <feature-group> 607 <uses-feature /> 608 </feature-group> 609 </manifest>)EOF"; 610 EXPECT_THAT(Verify(input), IsNull()); 611 } 612 613 TEST_F(ManifestFixerTest, ApplicationInjectDebuggable) { 614 ManifestFixerOptions options; 615 options.debug_mode = true; 616 617 std::string no_d = R"( 618 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 619 package="android"> 620 <application> 621 </application> 622 </manifest>)"; 623 624 std::string false_d = R"( 625 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 626 package="android"> 627 <application android:debuggable="false"> 628 </application> 629 </manifest>)"; 630 631 std::string true_d = R"( 632 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 633 package="android"> 634 <application android:debuggable="true"> 635 </application> 636 </manifest>)"; 637 638 // Inject the debuggable attribute when the attribute is not present and the 639 // flag is present 640 std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(no_d, options); 641 EXPECT_THAT(manifest->root.get()->FindChildWithAttribute( 642 {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull()); 643 644 // Set the debuggable flag to true if the attribute is false and the flag is 645 // present 646 manifest = VerifyWithOptions(false_d, options); 647 EXPECT_THAT(manifest->root.get()->FindChildWithAttribute( 648 {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull()); 649 650 // Keep debuggable flag true if the attribute is true and the flag is present 651 manifest = VerifyWithOptions(true_d, options); 652 EXPECT_THAT(manifest->root.get()->FindChildWithAttribute( 653 {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull()); 654 655 // Do not inject the debuggable attribute when the attribute is not present 656 // and the flag is not present 657 manifest = Verify(no_d); 658 EXPECT_THAT(manifest->root.get()->FindChildWithAttribute( 659 {}, "application", xml::kSchemaAndroid, "debuggable", "true"), IsNull()); 660 661 // Do not set the debuggable flag to true if the attribute is false and the 662 // flag is not present 663 manifest = Verify(false_d); 664 EXPECT_THAT(manifest->root.get()->FindChildWithAttribute( 665 {}, "application", xml::kSchemaAndroid, "debuggable", "true"), IsNull()); 666 667 // Keep debuggable flag true if the attribute is true and the flag is not 668 // present 669 manifest = Verify(true_d); 670 EXPECT_THAT(manifest->root.get()->FindChildWithAttribute( 671 {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull()); 672 } 673 674 TEST_F(ManifestFixerTest, ApplicationProfileable) { 675 std::string shell = R"( 676 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 677 package="android"> 678 <application> 679 <profileable android:shell="true"/> 680 </application> 681 </manifest>)"; 682 EXPECT_THAT(Verify(shell), NotNull()); 683 std::string noshell = R"( 684 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 685 package="android"> 686 <application> 687 <profileable/> 688 </application> 689 </manifest>)"; 690 EXPECT_THAT(Verify(noshell), NotNull()); 691 } 692 693 TEST_F(ManifestFixerTest, IgnoreNamespacedElements) { 694 std::string input = R"EOF( 695 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 696 package="android"> 697 <special:tag whoo="true" xmlns:special="http://google.com" /> 698 </manifest>)EOF"; 699 EXPECT_THAT(Verify(input), NotNull()); 700 } 701 702 TEST_F(ManifestFixerTest, DoNotIgnoreNonNamespacedElements) { 703 std::string input = R"EOF( 704 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 705 package="android"> 706 <tag whoo="true" /> 707 </manifest>)EOF"; 708 EXPECT_THAT(Verify(input), IsNull()); 709 } 710 711 TEST_F(ManifestFixerTest, SupportKeySets) { 712 std::string input = R"( 713 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 714 package="android"> 715 <key-sets> 716 <key-set android:name="old-set"> 717 <public-key android:name="old-key" android:value="some+old+key" /> 718 </key-set> 719 <key-set android:name="new-set"> 720 <public-key android:name="new-key" android:value="some+new+key" /> 721 </key-set> 722 <upgrade-key-set android:name="old-set" /> 723 <upgrade-key-set android:name="new-set" /> 724 </key-sets> 725 </manifest>)"; 726 EXPECT_THAT(Verify(input), NotNull()); 727 } 728 729 TEST_F(ManifestFixerTest, InsertCompileSdkVersions) { 730 std::string input = R"( 731 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" />)"; 732 ManifestFixerOptions options; 733 options.compile_sdk_version = {"28"}; 734 options.compile_sdk_version_codename = {"P"}; 735 736 std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options); 737 ASSERT_THAT(manifest, NotNull()); 738 739 xml::Attribute* attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersion"); 740 ASSERT_THAT(attr, NotNull()); 741 EXPECT_THAT(attr->value, StrEq("28")); 742 743 attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersionCodename"); 744 ASSERT_THAT(attr, NotNull()); 745 EXPECT_THAT(attr->value, StrEq("P")); 746 747 attr = manifest->root->FindAttribute("", "platformBuildVersionCode"); 748 ASSERT_THAT(attr, NotNull()); 749 EXPECT_THAT(attr->value, StrEq("28")); 750 751 attr = manifest->root->FindAttribute("", "platformBuildVersionName"); 752 ASSERT_THAT(attr, NotNull()); 753 EXPECT_THAT(attr->value, StrEq("P")); 754 } 755 756 TEST_F(ManifestFixerTest, OverrideCompileSdkVersions) { 757 std::string input = R"( 758 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" 759 compileSdkVersion="27" compileSdkVersionCodename="O" 760 platformBuildVersionCode="27" platformBuildVersionName="O"/>)"; 761 ManifestFixerOptions options; 762 options.compile_sdk_version = {"28"}; 763 options.compile_sdk_version_codename = {"P"}; 764 765 std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options); 766 ASSERT_THAT(manifest, NotNull()); 767 768 xml::Attribute* attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersion"); 769 ASSERT_THAT(attr, NotNull()); 770 EXPECT_THAT(attr->value, StrEq("28")); 771 772 attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersionCodename"); 773 ASSERT_THAT(attr, NotNull()); 774 EXPECT_THAT(attr->value, StrEq("P")); 775 776 attr = manifest->root->FindAttribute("", "platformBuildVersionCode"); 777 ASSERT_THAT(attr, NotNull()); 778 EXPECT_THAT(attr->value, StrEq("28")); 779 780 attr = manifest->root->FindAttribute("", "platformBuildVersionName"); 781 ASSERT_THAT(attr, NotNull()); 782 EXPECT_THAT(attr->value, StrEq("P")); 783 } 784 785 TEST_F(ManifestFixerTest, UnexpectedElementsInManifest) { 786 std::string input = R"( 787 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 788 package="android"> 789 <beep/> 790 </manifest>)"; 791 ManifestFixerOptions options; 792 options.warn_validation = true; 793 794 // Unexpected element should result in a warning if the flag is set to 'true'. 795 std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options); 796 ASSERT_THAT(manifest, NotNull()); 797 798 // Unexpected element should result in an error if the flag is set to 'false'. 799 options.warn_validation = false; 800 manifest = VerifyWithOptions(input, options); 801 ASSERT_THAT(manifest, IsNull()); 802 803 // By default the flag should be set to 'false'. 804 manifest = Verify(input); 805 ASSERT_THAT(manifest, IsNull()); 806 } 807 808 TEST_F(ManifestFixerTest, UsesLibraryMustHaveNonEmptyName) { 809 std::string input = R"( 810 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 811 package="android"> 812 <application> 813 <uses-library android:name="" /> 814 </application> 815 </manifest>)"; 816 EXPECT_THAT(Verify(input), IsNull()); 817 818 input = R"( 819 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 820 package="android"> 821 <application> 822 <uses-library /> 823 </application> 824 </manifest>)"; 825 EXPECT_THAT(Verify(input), IsNull()); 826 827 input = R"( 828 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 829 package="android"> 830 <application> 831 <uses-library android:name="blahhh" /> 832 </application> 833 </manifest>)"; 834 EXPECT_THAT(Verify(input), NotNull()); 835 } 836 837 } // namespace aapt 838