1// Copyright 2020 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package java 16 17import ( 18 "fmt" 19 "reflect" 20 "strings" 21 "testing" 22 23 "github.com/google/blueprint/proptools" 24 25 "android/soong/android" 26) 27 28func TestAndroidAppImport(t *testing.T) { 29 ctx, _ := testJava(t, ` 30 android_app_import { 31 name: "foo", 32 apk: "prebuilts/apk/app.apk", 33 certificate: "platform", 34 dex_preopt: { 35 enabled: true, 36 }, 37 } 38 `) 39 40 variant := ctx.ModuleForTests("foo", "android_common") 41 42 // Check dexpreopt outputs. 43 if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil || 44 variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil { 45 t.Errorf("can't find dexpreopt outputs") 46 } 47 48 // Check cert signing flag. 49 signedApk := variant.Output("signed/foo.apk") 50 signingFlag := signedApk.Args["certificates"] 51 expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8" 52 if expected != signingFlag { 53 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag) 54 } 55 rule := variant.Rule("genProvenanceMetaData") 56 android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String()) 57 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String()) 58 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"]) 59 android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"]) 60} 61 62func TestAndroidAppImport_NoDexPreopt(t *testing.T) { 63 ctx, _ := testJava(t, ` 64 android_app_import { 65 name: "foo", 66 apk: "prebuilts/apk/app.apk", 67 certificate: "platform", 68 dex_preopt: { 69 enabled: false, 70 }, 71 } 72 `) 73 74 variant := ctx.ModuleForTests("foo", "android_common") 75 76 // Check dexpreopt outputs. They shouldn't exist. 77 if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule != nil || 78 variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule != nil { 79 t.Errorf("dexpreopt shouldn't have run.") 80 } 81 82 rule := variant.Rule("genProvenanceMetaData") 83 android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String()) 84 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String()) 85 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"]) 86 android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"]) 87} 88 89func TestAndroidAppImport_Presigned(t *testing.T) { 90 ctx, _ := testJava(t, ` 91 android_app_import { 92 name: "foo", 93 apk: "prebuilts/apk/app.apk", 94 presigned: true, 95 dex_preopt: { 96 enabled: true, 97 }, 98 } 99 `) 100 101 variant := ctx.ModuleForTests("foo", "android_common") 102 103 // Check dexpreopt outputs. 104 if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil || 105 variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil { 106 t.Errorf("can't find dexpreopt outputs") 107 } 108 // Make sure signing was skipped and aligning was done. 109 if variant.MaybeOutput("signed/foo.apk").Rule != nil { 110 t.Errorf("signing rule shouldn't be included.") 111 } 112 if variant.MaybeOutput("zip-aligned/foo.apk").Rule == nil { 113 t.Errorf("can't find aligning rule") 114 } 115 116 rule := variant.Rule("genProvenanceMetaData") 117 android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String()) 118 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String()) 119 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"]) 120 android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"]) 121} 122 123func TestAndroidAppImport_SigningLineage(t *testing.T) { 124 ctx, _ := testJava(t, ` 125 android_app_import { 126 name: "foo", 127 apk: "prebuilts/apk/app.apk", 128 certificate: "platform", 129 additional_certificates: [":additional_certificate"], 130 lineage: "lineage.bin", 131 rotationMinSdkVersion: "32", 132 } 133 134 android_app_certificate { 135 name: "additional_certificate", 136 certificate: "cert/additional_cert", 137 } 138 `) 139 140 variant := ctx.ModuleForTests("foo", "android_common") 141 142 signedApk := variant.Output("signed/foo.apk") 143 // Check certificates 144 certificatesFlag := signedApk.Args["certificates"] 145 expected := "build/make/target/product/security/platform.x509.pem " + 146 "build/make/target/product/security/platform.pk8 " + 147 "cert/additional_cert.x509.pem cert/additional_cert.pk8" 148 if expected != certificatesFlag { 149 t.Errorf("Incorrect certificates flags, expected: %q, got: %q", expected, certificatesFlag) 150 } 151 152 // Check cert signing flags. 153 actualCertSigningFlags := signedApk.Args["flags"] 154 expectedCertSigningFlags := "--lineage lineage.bin --rotation-min-sdk-version 32" 155 if expectedCertSigningFlags != actualCertSigningFlags { 156 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expectedCertSigningFlags, actualCertSigningFlags) 157 } 158 159 rule := variant.Rule("genProvenanceMetaData") 160 android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String()) 161 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String()) 162 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"]) 163 android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"]) 164} 165 166func TestAndroidAppImport_SigningLineageFilegroup(t *testing.T) { 167 ctx, _ := testJava(t, ` 168 android_app_import { 169 name: "foo", 170 apk: "prebuilts/apk/app.apk", 171 certificate: "platform", 172 lineage: ":lineage_bin", 173 } 174 175 filegroup { 176 name: "lineage_bin", 177 srcs: ["lineage.bin"], 178 } 179 `) 180 181 variant := ctx.ModuleForTests("foo", "android_common") 182 183 signedApk := variant.Output("signed/foo.apk") 184 // Check cert signing lineage flag. 185 signingFlag := signedApk.Args["flags"] 186 expected := "--lineage lineage.bin" 187 if expected != signingFlag { 188 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag) 189 } 190 191 rule := variant.Rule("genProvenanceMetaData") 192 android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String()) 193 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String()) 194 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"]) 195 android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"]) 196} 197 198func TestAndroidAppImport_DefaultDevCert(t *testing.T) { 199 ctx, _ := testJava(t, ` 200 android_app_import { 201 name: "foo", 202 apk: "prebuilts/apk/app.apk", 203 default_dev_cert: true, 204 dex_preopt: { 205 enabled: true, 206 }, 207 } 208 `) 209 210 variant := ctx.ModuleForTests("foo", "android_common") 211 212 // Check dexpreopt outputs. 213 if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil || 214 variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil { 215 t.Errorf("can't find dexpreopt outputs") 216 } 217 218 // Check cert signing flag. 219 signedApk := variant.Output("signed/foo.apk") 220 signingFlag := signedApk.Args["certificates"] 221 expected := "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8" 222 if expected != signingFlag { 223 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag) 224 } 225 226 rule := variant.Rule("genProvenanceMetaData") 227 android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String()) 228 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String()) 229 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"]) 230 android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"]) 231} 232 233func TestAndroidAppImport_DpiVariants(t *testing.T) { 234 bp := ` 235 android_app_import { 236 name: "foo", 237 apk: "prebuilts/apk/app.apk", 238 dpi_variants: { 239 xhdpi: { 240 apk: "prebuilts/apk/app_xhdpi.apk", 241 }, 242 xxhdpi: { 243 apk: "prebuilts/apk/app_xxhdpi.apk", 244 }, 245 }, 246 presigned: true, 247 dex_preopt: { 248 enabled: true, 249 }, 250 } 251 ` 252 testCases := []struct { 253 name string 254 aaptPreferredConfig *string 255 aaptPrebuiltDPI []string 256 expected string 257 expectedProvenanceMetaDataArtifactPath string 258 }{ 259 { 260 name: "no preferred", 261 aaptPreferredConfig: nil, 262 aaptPrebuiltDPI: []string{}, 263 expected: "verify_uses_libraries/apk/app.apk", 264 expectedProvenanceMetaDataArtifactPath: "prebuilts/apk/app.apk", 265 }, 266 { 267 name: "AAPTPreferredConfig matches", 268 aaptPreferredConfig: proptools.StringPtr("xhdpi"), 269 aaptPrebuiltDPI: []string{"xxhdpi", "ldpi"}, 270 expected: "verify_uses_libraries/apk/app_xhdpi.apk", 271 expectedProvenanceMetaDataArtifactPath: "prebuilts/apk/app_xhdpi.apk", 272 }, 273 { 274 name: "AAPTPrebuiltDPI matches", 275 aaptPreferredConfig: proptools.StringPtr("mdpi"), 276 aaptPrebuiltDPI: []string{"xxhdpi", "xhdpi"}, 277 expected: "verify_uses_libraries/apk/app_xxhdpi.apk", 278 expectedProvenanceMetaDataArtifactPath: "prebuilts/apk/app_xxhdpi.apk", 279 }, 280 { 281 name: "non-first AAPTPrebuiltDPI matches", 282 aaptPreferredConfig: proptools.StringPtr("mdpi"), 283 aaptPrebuiltDPI: []string{"ldpi", "xhdpi"}, 284 expected: "verify_uses_libraries/apk/app_xhdpi.apk", 285 expectedProvenanceMetaDataArtifactPath: "prebuilts/apk/app_xhdpi.apk", 286 }, 287 { 288 name: "no matches", 289 aaptPreferredConfig: proptools.StringPtr("mdpi"), 290 aaptPrebuiltDPI: []string{"ldpi", "xxxhdpi"}, 291 expected: "verify_uses_libraries/apk/app.apk", 292 expectedProvenanceMetaDataArtifactPath: "prebuilts/apk/app.apk", 293 }, 294 } 295 296 for _, test := range testCases { 297 result := android.GroupFixturePreparers( 298 PrepareForTestWithJavaDefaultModules, 299 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 300 variables.AAPTPreferredConfig = test.aaptPreferredConfig 301 variables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI 302 }), 303 ).RunTestWithBp(t, bp) 304 305 variant := result.ModuleForTests("foo", "android_common") 306 input := variant.Output("jnis-uncompressed/foo.apk").Input.String() 307 if strings.HasSuffix(input, test.expected) { 308 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, input) 309 } 310 311 provenanceMetaDataRule := variant.Rule("genProvenanceMetaData") 312 android.AssertStringEquals(t, "Invalid input", test.expectedProvenanceMetaDataArtifactPath, provenanceMetaDataRule.Inputs[0].String()) 313 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", provenanceMetaDataRule.Output.String()) 314 android.AssertStringEquals(t, "Invalid args", "foo", provenanceMetaDataRule.Args["module_name"]) 315 android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", provenanceMetaDataRule.Args["install_path"]) 316 } 317} 318 319func TestAndroidAppImport_Filename(t *testing.T) { 320 ctx, _ := testJava(t, ` 321 android_app_import { 322 name: "foo", 323 apk: "prebuilts/apk/app.apk", 324 presigned: true, 325 } 326 327 android_app_import { 328 name: "bar", 329 apk: "prebuilts/apk/app.apk", 330 presigned: true, 331 filename: "bar_sample.apk" 332 } 333 `) 334 335 testCases := []struct { 336 name string 337 expected string 338 onDevice string 339 expectedArtifactPath string 340 expectedMetaDataPath string 341 }{ 342 { 343 name: "foo", 344 expected: "foo.apk", 345 onDevice: "/system/app/foo/foo.apk", 346 expectedArtifactPath: "prebuilts/apk/app.apk", 347 expectedMetaDataPath: "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", 348 }, 349 { 350 name: "bar", 351 expected: "bar_sample.apk", 352 onDevice: "/system/app/bar/bar_sample.apk", 353 expectedArtifactPath: "prebuilts/apk/app.apk", 354 expectedMetaDataPath: "out/soong/.intermediates/provenance_metadata/bar/provenance_metadata.textproto", 355 }, 356 } 357 358 for _, test := range testCases { 359 variant := ctx.ModuleForTests(test.name, "android_common") 360 if variant.MaybeOutput(test.expected).Rule == nil { 361 t.Errorf("can't find output named %q - all outputs: %v", test.expected, variant.AllOutputs()) 362 } 363 364 a := variant.Module().(*AndroidAppImport) 365 expectedValues := []string{test.expected} 366 entries := android.AndroidMkEntriesForTest(t, ctx, a)[0] 367 actualValues := entries.EntryMap["LOCAL_INSTALLED_MODULE_STEM"] 368 if !reflect.DeepEqual(actualValues, expectedValues) { 369 t.Errorf("Incorrect LOCAL_INSTALLED_MODULE_STEM value '%s', expected '%s'", 370 actualValues, expectedValues) 371 } 372 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "android_app_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) 373 374 rule := variant.Rule("genProvenanceMetaData") 375 android.AssertStringEquals(t, "Invalid input", test.expectedArtifactPath, rule.Inputs[0].String()) 376 android.AssertStringEquals(t, "Invalid output", test.expectedMetaDataPath, rule.Output.String()) 377 android.AssertStringEquals(t, "Invalid args", test.name, rule.Args["module_name"]) 378 android.AssertStringEquals(t, "Invalid args", test.onDevice, rule.Args["install_path"]) 379 } 380} 381 382func TestAndroidAppImport_ArchVariants(t *testing.T) { 383 // The test config's target arch is ARM64. 384 testCases := []struct { 385 name string 386 bp string 387 expected string 388 artifactPath string 389 metaDataPath string 390 installPath string 391 }{ 392 { 393 name: "matching arch", 394 bp: ` 395 android_app_import { 396 name: "foo", 397 apk: "prebuilts/apk/app.apk", 398 arch: { 399 arm64: { 400 apk: "prebuilts/apk/app_arm64.apk", 401 }, 402 }, 403 presigned: true, 404 dex_preopt: { 405 enabled: true, 406 }, 407 } 408 `, 409 expected: "verify_uses_libraries/apk/app_arm64.apk", 410 artifactPath: "prebuilts/apk/app_arm64.apk", 411 installPath: "/system/app/foo/foo.apk", 412 }, 413 { 414 name: "matching arch without default", 415 bp: ` 416 android_app_import { 417 name: "foo", 418 apk: "prebuilts/apk/app.apk", 419 arch: { 420 arm64: { 421 apk: "prebuilts/apk/app_arm64.apk", 422 }, 423 }, 424 presigned: true, 425 dex_preopt: { 426 enabled: true, 427 }, 428 } 429 `, 430 expected: "verify_uses_libraries/apk/app_arm64.apk", 431 artifactPath: "prebuilts/apk/app_arm64.apk", 432 installPath: "/system/app/foo/foo.apk", 433 }, 434 { 435 name: "no matching arch", 436 bp: ` 437 android_app_import { 438 name: "foo", 439 apk: "prebuilts/apk/app.apk", 440 arch: { 441 arm: { 442 apk: "prebuilts/apk/app_arm.apk", 443 }, 444 }, 445 presigned: true, 446 dex_preopt: { 447 enabled: true, 448 }, 449 } 450 `, 451 expected: "verify_uses_libraries/apk/app.apk", 452 artifactPath: "prebuilts/apk/app.apk", 453 installPath: "/system/app/foo/foo.apk", 454 }, 455 { 456 name: "no matching arch without default", 457 bp: ` 458 android_app_import { 459 name: "foo", 460 arch: { 461 arm: { 462 apk: "prebuilts/apk/app_arm.apk", 463 }, 464 }, 465 presigned: true, 466 dex_preopt: { 467 enabled: true, 468 }, 469 } 470 `, 471 expected: "", 472 artifactPath: "prebuilts/apk/app_arm.apk", 473 installPath: "/system/app/foo/foo.apk", 474 }, 475 { 476 name: "matching arch and dpi_variants", 477 bp: ` 478 android_app_import { 479 name: "foo", 480 apk: "prebuilts/apk/app.apk", 481 arch: { 482 arm64: { 483 apk: "prebuilts/apk/app_arm64.apk", 484 dpi_variants: { 485 mdpi: { 486 apk: "prebuilts/apk/app_arm64_mdpi.apk", 487 }, 488 xhdpi: { 489 apk: "prebuilts/apk/app_arm64_xhdpi.apk", 490 }, 491 }, 492 }, 493 }, 494 presigned: true, 495 dex_preopt: { 496 enabled: true, 497 }, 498 } 499 `, 500 expected: "verify_uses_libraries/apk/app_arm64_xhdpi.apk", 501 artifactPath: "prebuilts/apk/app_arm64_xhdpi.apk", 502 installPath: "/system/app/foo/foo.apk", 503 }, 504 } 505 506 for _, test := range testCases { 507 t.Run(test.name, func(t *testing.T) { 508 ctx, _ := testJava(t, test.bp) 509 510 variant := ctx.ModuleForTests("foo", "android_common") 511 if test.expected == "" { 512 if variant.Module().Enabled(android.PanickingConfigAndErrorContext(ctx)) { 513 t.Error("module should have been disabled, but wasn't") 514 } 515 rule := variant.MaybeRule("genProvenanceMetaData") 516 android.AssertDeepEquals(t, "Provenance metadata is not empty", android.TestingBuildParams{}, rule) 517 return 518 } 519 input := variant.Output("jnis-uncompressed/foo.apk").Input.String() 520 if strings.HasSuffix(input, test.expected) { 521 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, input) 522 } 523 rule := variant.Rule("genProvenanceMetaData") 524 android.AssertStringEquals(t, "Invalid input", test.artifactPath, rule.Inputs[0].String()) 525 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String()) 526 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"]) 527 android.AssertStringEquals(t, "Invalid args", test.installPath, rule.Args["install_path"]) 528 }) 529 } 530} 531 532func TestAndroidAppImport_SoongConfigVariables(t *testing.T) { 533 testCases := []struct { 534 name string 535 bp string 536 expected string 537 artifactPath string 538 metaDataPath string 539 installPath string 540 }{ 541 { 542 name: "matching arch", 543 bp: ` 544 soong_config_module_type { 545 name: "my_android_app_import", 546 module_type: "android_app_import", 547 config_namespace: "my_namespace", 548 value_variables: ["my_apk_var"], 549 properties: ["apk"], 550 } 551 soong_config_value_variable { 552 name: "my_apk_var", 553 } 554 my_android_app_import { 555 name: "foo", 556 soong_config_variables: { 557 my_apk_var: { 558 apk: "prebuilts/apk/%s.apk", 559 }, 560 }, 561 presigned: true, 562 dex_preopt: { 563 enabled: true, 564 }, 565 } 566 `, 567 expected: "verify_uses_libraries/apk/name_from_soong_config.apk", 568 artifactPath: "prebuilts/apk/name_from_soong_config.apk", 569 installPath: "/system/app/foo/foo.apk", 570 }, 571 } 572 573 for _, test := range testCases { 574 t.Run(test.name, func(t *testing.T) { 575 ctx := android.GroupFixturePreparers( 576 prepareForJavaTest, 577 android.PrepareForTestWithSoongConfigModuleBuildComponents, 578 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 579 variables.VendorVars = map[string]map[string]string{ 580 "my_namespace": { 581 "my_apk_var": "name_from_soong_config", 582 }, 583 } 584 }), 585 ).RunTestWithBp(t, test.bp).TestContext 586 587 variant := ctx.ModuleForTests("foo", "android_common") 588 if test.expected == "" { 589 if variant.Module().Enabled(android.PanickingConfigAndErrorContext(ctx)) { 590 t.Error("module should have been disabled, but wasn't") 591 } 592 rule := variant.MaybeRule("genProvenanceMetaData") 593 android.AssertDeepEquals(t, "Provenance metadata is not empty", android.TestingBuildParams{}, rule) 594 return 595 } 596 input := variant.Output("jnis-uncompressed/foo.apk").Input.String() 597 if strings.HasSuffix(input, test.expected) { 598 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, input) 599 } 600 rule := variant.Rule("genProvenanceMetaData") 601 android.AssertStringEquals(t, "Invalid input", test.artifactPath, rule.Inputs[0].String()) 602 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String()) 603 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"]) 604 android.AssertStringEquals(t, "Invalid args", test.installPath, rule.Args["install_path"]) 605 }) 606 } 607} 608 609func TestAndroidAppImport_overridesDisabledAndroidApp(t *testing.T) { 610 ctx, _ := testJava(t, ` 611 android_app { 612 name: "foo", 613 srcs: ["a.java"], 614 enabled: false, 615 } 616 617 android_app_import { 618 name: "foo", 619 apk: "prebuilts/apk/app.apk", 620 certificate: "platform", 621 prefer: true, 622 } 623 `) 624 625 variant := ctx.ModuleForTests("prebuilt_foo", "android_common") 626 a := variant.Module().(*AndroidAppImport) 627 // The prebuilt module should still be enabled and active even if the source-based counterpart 628 // is disabled. 629 if !a.prebuilt.UsePrebuilt() { 630 t.Errorf("prebuilt foo module is not active") 631 } 632 if !a.Enabled(android.PanickingConfigAndErrorContext(ctx)) { 633 t.Errorf("prebuilt foo module is disabled") 634 } 635} 636 637func TestAndroidAppImport_relativeInstallPath(t *testing.T) { 638 bp := ` 639 android_app_import { 640 name: "no_relative_install_path", 641 apk: "prebuilts/apk/app.apk", 642 presigned: true, 643 } 644 645 android_app_import { 646 name: "relative_install_path", 647 apk: "prebuilts/apk/app.apk", 648 presigned: true, 649 relative_install_path: "my/path", 650 } 651 652 android_app_import { 653 name: "privileged_relative_install_path", 654 apk: "prebuilts/apk/app.apk", 655 presigned: true, 656 privileged: true, 657 relative_install_path: "my/path" 658 } 659 ` 660 testCases := []struct { 661 name string 662 expectedInstallPath string 663 errorMessage string 664 }{ 665 { 666 name: "no_relative_install_path", 667 expectedInstallPath: "out/soong/target/product/test_device/system/app/no_relative_install_path/no_relative_install_path.apk", 668 errorMessage: "Install path is not correct when relative_install_path is missing", 669 }, 670 { 671 name: "relative_install_path", 672 expectedInstallPath: "out/soong/target/product/test_device/system/app/my/path/relative_install_path/relative_install_path.apk", 673 errorMessage: "Install path is not correct for app when relative_install_path is present", 674 }, 675 { 676 name: "privileged_relative_install_path", 677 expectedInstallPath: "out/soong/target/product/test_device/system/priv-app/my/path/privileged_relative_install_path/privileged_relative_install_path.apk", 678 errorMessage: "Install path is not correct for privileged app when relative_install_path is present", 679 }, 680 } 681 for _, testCase := range testCases { 682 ctx, _ := testJava(t, bp) 683 mod := ctx.ModuleForTests(testCase.name, "android_common").Module().(*AndroidAppImport) 684 android.AssertPathRelativeToTopEquals(t, testCase.errorMessage, testCase.expectedInstallPath, mod.installPath) 685 } 686} 687 688func TestAndroidTestImport(t *testing.T) { 689 ctx, _ := testJava(t, ` 690 android_test_import { 691 name: "foo", 692 apk: "prebuilts/apk/app.apk", 693 presigned: true, 694 data: [ 695 "testdata/data", 696 ], 697 } 698 `) 699 700 test := ctx.ModuleForTests("foo", "android_common").Module().(*AndroidTestImport) 701 702 // Check android mks. 703 entries := android.AndroidMkEntriesForTest(t, ctx, test)[0] 704 expected := []string{"tests"} 705 actual := entries.EntryMap["LOCAL_MODULE_TAGS"] 706 if !reflect.DeepEqual(expected, actual) { 707 t.Errorf("Unexpected module tags - expected: %q, actual: %q", expected, actual) 708 } 709 expected = []string{"testdata/data:testdata/data"} 710 actual = entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"] 711 if !reflect.DeepEqual(expected, actual) { 712 t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual) 713 } 714} 715 716func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) { 717 ctx, _ := testJava(t, ` 718 android_test_import { 719 name: "foo", 720 apk: "prebuilts/apk/app.apk", 721 certificate: "cert/new_cert", 722 data: [ 723 "testdata/data", 724 ], 725 } 726 727 android_test_import { 728 name: "foo_presigned", 729 apk: "prebuilts/apk/app.apk", 730 presigned: true, 731 data: [ 732 "testdata/data", 733 ], 734 } 735 `) 736 737 variant := ctx.ModuleForTests("foo", "android_common") 738 jniRule := variant.Output("jnis-uncompressed/foo.apk").BuildParams.Rule.String() 739 if jniRule == android.Cp.String() { 740 t.Errorf("Unexpected JNI uncompress rule command: " + jniRule) 741 } 742 743 variant = ctx.ModuleForTests("foo_presigned", "android_common") 744 jniRule = variant.Output("jnis-uncompressed/foo_presigned.apk").BuildParams.Rule.String() 745 if jniRule != android.Cp.String() { 746 t.Errorf("Unexpected JNI uncompress rule: " + jniRule) 747 } 748 if variant.MaybeOutput("zip-aligned/foo_presigned.apk").Rule == nil { 749 t.Errorf("Presigned test apk should be aligned") 750 } 751} 752 753func TestAndroidTestImport_Preprocessed(t *testing.T) { 754 ctx, _ := testJava(t, ` 755 android_test_import { 756 name: "foo", 757 apk: "prebuilts/apk/app.apk", 758 presigned: true, 759 preprocessed: true, 760 } 761 `) 762 763 apkName := "foo.apk" 764 variant := ctx.ModuleForTests("foo", "android_common") 765 jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String() 766 if jniRule != android.Cp.String() { 767 t.Errorf("Unexpected JNI uncompress rule: " + jniRule) 768 } 769 770 // Make sure signing and aligning were skipped. 771 if variant.MaybeOutput("signed/"+apkName).Rule != nil { 772 t.Errorf("signing rule shouldn't be included for preprocessed.") 773 } 774 if variant.MaybeOutput("zip-aligned/"+apkName).Rule != nil { 775 t.Errorf("aligning rule shouldn't be for preprocessed") 776 } 777} 778 779func TestAndroidAppImport_Preprocessed(t *testing.T) { 780 ctx, _ := testJava(t, ` 781 android_app_import { 782 name: "foo", 783 apk: "prebuilts/apk/app.apk", 784 presigned: true, 785 preprocessed: true, 786 } 787 `) 788 789 apkName := "foo.apk" 790 variant := ctx.ModuleForTests("foo", "android_common") 791 outputBuildParams := variant.Output(apkName).BuildParams 792 if outputBuildParams.Rule.String() != android.Cp.String() { 793 t.Errorf("Unexpected prebuilt android_app_import rule: " + outputBuildParams.Rule.String()) 794 } 795 796 // Make sure compression and aligning were validated. 797 if outputBuildParams.Validation == nil { 798 t.Errorf("Expected validation rule, but was not found") 799 } 800 801 validationBuildParams := variant.Output("validated-prebuilt/check.stamp").BuildParams 802 if validationBuildParams.Rule.String() != checkPresignedApkRule.String() { 803 t.Errorf("Unexpected validation rule: " + validationBuildParams.Rule.String()) 804 } 805} 806 807func TestAndroidTestImport_UncompressDex(t *testing.T) { 808 testCases := []struct { 809 name string 810 bp string 811 }{ 812 { 813 name: "normal", 814 bp: ` 815 android_app_import { 816 name: "foo", 817 presigned: true, 818 apk: "prebuilts/apk/app.apk", 819 } 820 `, 821 }, 822 { 823 name: "privileged", 824 bp: ` 825 android_app_import { 826 name: "foo", 827 presigned: true, 828 privileged: true, 829 apk: "prebuilts/apk/app.apk", 830 } 831 `, 832 }, 833 } 834 835 test := func(t *testing.T, bp string, unbundled bool, dontUncompressPrivAppDexs bool) { 836 t.Helper() 837 838 result := android.GroupFixturePreparers( 839 prepareForJavaTest, 840 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 841 if unbundled { 842 variables.Unbundled_build = proptools.BoolPtr(true) 843 } 844 variables.UncompressPrivAppDex = proptools.BoolPtr(!dontUncompressPrivAppDexs) 845 }), 846 ).RunTestWithBp(t, bp) 847 848 foo := result.ModuleForTests("foo", "android_common") 849 actual := foo.MaybeRule("uncompress-dex").Rule != nil 850 851 expect := !unbundled 852 if strings.Contains(bp, "privileged: true") { 853 if dontUncompressPrivAppDexs { 854 expect = false 855 } else { 856 // TODO(b/194504107): shouldn't priv-apps be always uncompressed unless 857 // DONT_UNCOMPRESS_PRIV_APPS_DEXS is true (regardless of unbundling)? 858 // expect = true 859 } 860 } 861 862 android.AssertBoolEquals(t, "uncompress dex", expect, actual) 863 } 864 865 for _, unbundled := range []bool{false, true} { 866 for _, dontUncompressPrivAppDexs := range []bool{false, true} { 867 for _, tt := range testCases { 868 name := fmt.Sprintf("%s,unbundled:%t,dontUncompressPrivAppDexs:%t", 869 tt.name, unbundled, dontUncompressPrivAppDexs) 870 t.Run(name, func(t *testing.T) { 871 test(t, tt.bp, unbundled, dontUncompressPrivAppDexs) 872 }) 873 } 874 } 875 } 876} 877 878func TestAppImportMissingCertificateAllowMissingDependencies(t *testing.T) { 879 result := android.GroupFixturePreparers( 880 PrepareForTestWithJavaDefaultModules, 881 android.PrepareForTestWithAllowMissingDependencies, 882 android.PrepareForTestWithAndroidMk, 883 ).RunTestWithBp(t, ` 884 android_app_import { 885 name: "foo", 886 apk: "a.apk", 887 certificate: ":missing_certificate", 888 }`) 889 890 foo := result.ModuleForTests("foo", "android_common") 891 fooApk := foo.Output("signed/foo.apk") 892 if fooApk.Rule != android.ErrorRule { 893 t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String()) 894 } 895 android.AssertStringDoesContain(t, "expected error rule message", fooApk.Args["error"], "missing dependencies: missing_certificate\n") 896} 897