blob: cae41d0e7ede9d9ea3d46d64d036afc25dc55c7c [file] [log] [blame]
Jaewoong Jungf9b44652020-12-21 12:29:12 -08001// 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 "reflect"
19 "regexp"
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/oat/arm64/package.vdex").Rule == nil ||
44 variant.MaybeOutput("dexpreopt/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}
56
57func TestAndroidAppImport_NoDexPreopt(t *testing.T) {
58 ctx, _ := testJava(t, `
59 android_app_import {
60 name: "foo",
61 apk: "prebuilts/apk/app.apk",
62 certificate: "platform",
63 dex_preopt: {
64 enabled: false,
65 },
66 }
67 `)
68
69 variant := ctx.ModuleForTests("foo", "android_common")
70
71 // Check dexpreopt outputs. They shouldn't exist.
72 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule != nil ||
73 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule != nil {
74 t.Errorf("dexpreopt shouldn't have run.")
75 }
76}
77
78func TestAndroidAppImport_Presigned(t *testing.T) {
79 ctx, _ := testJava(t, `
80 android_app_import {
81 name: "foo",
82 apk: "prebuilts/apk/app.apk",
83 presigned: true,
84 dex_preopt: {
85 enabled: true,
86 },
87 }
88 `)
89
90 variant := ctx.ModuleForTests("foo", "android_common")
91
92 // Check dexpreopt outputs.
93 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
94 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
95 t.Errorf("can't find dexpreopt outputs")
96 }
97 // Make sure signing was skipped and aligning was done.
98 if variant.MaybeOutput("signed/foo.apk").Rule != nil {
99 t.Errorf("signing rule shouldn't be included.")
100 }
101 if variant.MaybeOutput("zip-aligned/foo.apk").Rule == nil {
102 t.Errorf("can't find aligning rule")
103 }
104}
105
106func TestAndroidAppImport_SigningLineage(t *testing.T) {
107 ctx, _ := testJava(t, `
108 android_app_import {
109 name: "foo",
110 apk: "prebuilts/apk/app.apk",
111 certificate: "platform",
Jaewoong Jung25ae8de2021-03-08 17:37:46 -0800112 additional_certificates: [":additional_certificate"],
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800113 lineage: "lineage.bin",
114 }
Jaewoong Jung25ae8de2021-03-08 17:37:46 -0800115
116 android_app_certificate {
117 name: "additional_certificate",
118 certificate: "cert/additional_cert",
119 }
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800120 `)
121
122 variant := ctx.ModuleForTests("foo", "android_common")
123
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800124 signedApk := variant.Output("signed/foo.apk")
Jaewoong Jung25ae8de2021-03-08 17:37:46 -0800125 // Check certificates
126 certificatesFlag := signedApk.Args["certificates"]
127 expected := "build/make/target/product/security/platform.x509.pem " +
128 "build/make/target/product/security/platform.pk8 " +
129 "cert/additional_cert.x509.pem cert/additional_cert.pk8"
130 if expected != certificatesFlag {
131 t.Errorf("Incorrect certificates flags, expected: %q, got: %q", expected, certificatesFlag)
132 }
133 // Check cert signing lineage flag.
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800134 signingFlag := signedApk.Args["flags"]
Jaewoong Jung25ae8de2021-03-08 17:37:46 -0800135 expected = "--lineage lineage.bin"
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800136 if expected != signingFlag {
137 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
138 }
139}
140
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800141func TestAndroidAppImport_SigningLineageFilegroup(t *testing.T) {
142 ctx, _ := testJava(t, `
143 android_app_import {
144 name: "foo",
145 apk: "prebuilts/apk/app.apk",
146 certificate: "platform",
147 lineage: ":lineage_bin",
148 }
149
150 filegroup {
151 name: "lineage_bin",
152 srcs: ["lineage.bin"],
153 }
154 `)
155
156 variant := ctx.ModuleForTests("foo", "android_common")
157
158 signedApk := variant.Output("signed/foo.apk")
159 // Check cert signing lineage flag.
160 signingFlag := signedApk.Args["flags"]
161 expected := "--lineage lineage.bin"
162 if expected != signingFlag {
163 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
164 }
165}
166
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800167func TestAndroidAppImport_DefaultDevCert(t *testing.T) {
168 ctx, _ := testJava(t, `
169 android_app_import {
170 name: "foo",
171 apk: "prebuilts/apk/app.apk",
172 default_dev_cert: true,
173 dex_preopt: {
174 enabled: true,
175 },
176 }
177 `)
178
179 variant := ctx.ModuleForTests("foo", "android_common")
180
181 // Check dexpreopt outputs.
182 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
183 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
184 t.Errorf("can't find dexpreopt outputs")
185 }
186
187 // Check cert signing flag.
188 signedApk := variant.Output("signed/foo.apk")
189 signingFlag := signedApk.Args["certificates"]
190 expected := "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8"
191 if expected != signingFlag {
192 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
193 }
194}
195
196func TestAndroidAppImport_DpiVariants(t *testing.T) {
197 bp := `
198 android_app_import {
199 name: "foo",
200 apk: "prebuilts/apk/app.apk",
201 dpi_variants: {
202 xhdpi: {
203 apk: "prebuilts/apk/app_xhdpi.apk",
204 },
205 xxhdpi: {
206 apk: "prebuilts/apk/app_xxhdpi.apk",
207 },
208 },
209 presigned: true,
210 dex_preopt: {
211 enabled: true,
212 },
213 }
214 `
215 testCases := []struct {
216 name string
217 aaptPreferredConfig *string
218 aaptPrebuiltDPI []string
219 expected string
220 }{
221 {
222 name: "no preferred",
223 aaptPreferredConfig: nil,
224 aaptPrebuiltDPI: []string{},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000225 expected: "verify_uses_libraries/apk/app.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800226 },
227 {
228 name: "AAPTPreferredConfig matches",
229 aaptPreferredConfig: proptools.StringPtr("xhdpi"),
230 aaptPrebuiltDPI: []string{"xxhdpi", "ldpi"},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000231 expected: "verify_uses_libraries/apk/app_xhdpi.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800232 },
233 {
234 name: "AAPTPrebuiltDPI matches",
235 aaptPreferredConfig: proptools.StringPtr("mdpi"),
236 aaptPrebuiltDPI: []string{"xxhdpi", "xhdpi"},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000237 expected: "verify_uses_libraries/apk/app_xxhdpi.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800238 },
239 {
240 name: "non-first AAPTPrebuiltDPI matches",
241 aaptPreferredConfig: proptools.StringPtr("mdpi"),
242 aaptPrebuiltDPI: []string{"ldpi", "xhdpi"},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000243 expected: "verify_uses_libraries/apk/app_xhdpi.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800244 },
245 {
246 name: "no matches",
247 aaptPreferredConfig: proptools.StringPtr("mdpi"),
248 aaptPrebuiltDPI: []string{"ldpi", "xxxhdpi"},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000249 expected: "verify_uses_libraries/apk/app.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800250 },
251 }
252
253 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
254 for _, test := range testCases {
255 config := testAppConfig(nil, bp, nil)
256 config.TestProductVariables.AAPTPreferredConfig = test.aaptPreferredConfig
257 config.TestProductVariables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
258 ctx := testContext(config)
259
260 run(t, ctx, config)
261
262 variant := ctx.ModuleForTests("foo", "android_common")
263 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
264 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
265 if len(matches) != 2 {
266 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
267 }
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000268 if strings.HasSuffix(matches[1], test.expected) {
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800269 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
270 }
271 }
272}
273
274func TestAndroidAppImport_Filename(t *testing.T) {
Colin Crossaa255532020-07-03 13:18:24 -0700275 ctx, _ := testJava(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800276 android_app_import {
277 name: "foo",
278 apk: "prebuilts/apk/app.apk",
279 presigned: true,
280 }
281
282 android_app_import {
283 name: "bar",
284 apk: "prebuilts/apk/app.apk",
285 presigned: true,
286 filename: "bar_sample.apk"
287 }
288 `)
289
290 testCases := []struct {
291 name string
292 expected string
293 }{
294 {
295 name: "foo",
296 expected: "foo.apk",
297 },
298 {
299 name: "bar",
300 expected: "bar_sample.apk",
301 },
302 }
303
304 for _, test := range testCases {
305 variant := ctx.ModuleForTests(test.name, "android_common")
306 if variant.MaybeOutput(test.expected).Rule == nil {
307 t.Errorf("can't find output named %q - all outputs: %v", test.expected, variant.AllOutputs())
308 }
309
310 a := variant.Module().(*AndroidAppImport)
311 expectedValues := []string{test.expected}
Colin Crossaa255532020-07-03 13:18:24 -0700312 actualValues := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_INSTALLED_MODULE_STEM"]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800313 if !reflect.DeepEqual(actualValues, expectedValues) {
314 t.Errorf("Incorrect LOCAL_INSTALLED_MODULE_STEM value '%s', expected '%s'",
315 actualValues, expectedValues)
316 }
317 }
318}
319
320func TestAndroidAppImport_ArchVariants(t *testing.T) {
321 // The test config's target arch is ARM64.
322 testCases := []struct {
323 name string
324 bp string
325 expected string
326 }{
327 {
328 name: "matching arch",
329 bp: `
330 android_app_import {
331 name: "foo",
332 apk: "prebuilts/apk/app.apk",
333 arch: {
334 arm64: {
335 apk: "prebuilts/apk/app_arm64.apk",
336 },
337 },
338 presigned: true,
339 dex_preopt: {
340 enabled: true,
341 },
342 }
343 `,
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000344 expected: "verify_uses_libraries/apk/app_arm64.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800345 },
346 {
347 name: "no matching arch",
348 bp: `
349 android_app_import {
350 name: "foo",
351 apk: "prebuilts/apk/app.apk",
352 arch: {
353 arm: {
354 apk: "prebuilts/apk/app_arm.apk",
355 },
356 },
357 presigned: true,
358 dex_preopt: {
359 enabled: true,
360 },
361 }
362 `,
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000363 expected: "verify_uses_libraries/apk/app.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800364 },
365 {
366 name: "no matching arch without default",
367 bp: `
368 android_app_import {
369 name: "foo",
370 arch: {
371 arm: {
372 apk: "prebuilts/apk/app_arm.apk",
373 },
374 },
375 presigned: true,
376 dex_preopt: {
377 enabled: true,
378 },
379 }
380 `,
381 expected: "",
382 },
383 }
384
385 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
386 for _, test := range testCases {
387 ctx, _ := testJava(t, test.bp)
388
389 variant := ctx.ModuleForTests("foo", "android_common")
390 if test.expected == "" {
391 if variant.Module().Enabled() {
392 t.Error("module should have been disabled, but wasn't")
393 }
394 continue
395 }
396 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
397 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
398 if len(matches) != 2 {
399 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
400 }
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000401 if strings.HasSuffix(matches[1], test.expected) {
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800402 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
403 }
404 }
405}
406
407func TestAndroidAppImport_overridesDisabledAndroidApp(t *testing.T) {
408 ctx, _ := testJava(t, `
409 android_app {
410 name: "foo",
411 srcs: ["a.java"],
412 enabled: false,
413 }
414
415 android_app_import {
416 name: "foo",
417 apk: "prebuilts/apk/app.apk",
418 certificate: "platform",
419 prefer: true,
420 }
421 `)
422
423 variant := ctx.ModuleForTests("prebuilt_foo", "android_common")
424 a := variant.Module().(*AndroidAppImport)
425 // The prebuilt module should still be enabled and active even if the source-based counterpart
426 // is disabled.
427 if !a.prebuilt.UsePrebuilt() {
428 t.Errorf("prebuilt foo module is not active")
429 }
430 if !a.Enabled() {
431 t.Errorf("prebuilt foo module is disabled")
432 }
433}
434
Bill Peckhama036da92021-01-08 16:09:09 -0800435func TestAndroidAppImport_frameworkRes(t *testing.T) {
Colin Crossaa255532020-07-03 13:18:24 -0700436 ctx, _ := testJava(t, `
Bill Peckhama036da92021-01-08 16:09:09 -0800437 android_app_import {
438 name: "framework-res",
439 certificate: "platform",
440 apk: "package-res.apk",
441 prefer: true,
442 export_package_resources: true,
443 // Disable dexpreopt and verify_uses_libraries check as the app
444 // contains no Java code to be dexpreopted.
445 enforce_uses_libs: false,
446 dex_preopt: {
447 enabled: false,
448 },
449 }
450 `)
451
452 mod := ctx.ModuleForTests("prebuilt_framework-res", "android_common").Module()
453 a := mod.(*AndroidAppImport)
454
455 if !a.preprocessed {
456 t.Errorf("prebuilt framework-res is not preprocessed")
457 }
458
459 expectedInstallPath := buildDir + "/target/product/test_device/system/framework/framework-res.apk"
460
461 if a.dexpreopter.installPath.String() != expectedInstallPath {
462 t.Errorf("prebuilt framework-res installed to incorrect location, actual: %s, expected: %s", a.dexpreopter.installPath, expectedInstallPath)
463
464 }
465
Colin Crossaa255532020-07-03 13:18:24 -0700466 entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
Bill Peckhama036da92021-01-08 16:09:09 -0800467
468 expectedPath := "."
469 // From apk property above, in the root of the source tree.
470 expectedPrebuiltModuleFile := "package-res.apk"
471 // Verify that the apk is preprocessed: The export package is the same
472 // as the prebuilt.
473 expectedSoongResourceExportPackage := expectedPrebuiltModuleFile
474
475 actualPath := entries.EntryMap["LOCAL_PATH"]
476 actualPrebuiltModuleFile := entries.EntryMap["LOCAL_PREBUILT_MODULE_FILE"]
477 actualSoongResourceExportPackage := entries.EntryMap["LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE"]
478
479 if len(actualPath) != 1 {
480 t.Errorf("LOCAL_PATH incorrect len %d", len(actualPath))
481 } else if actualPath[0] != expectedPath {
482 t.Errorf("LOCAL_PATH mismatch, actual: %s, expected: %s", actualPath[0], expectedPath)
483 }
484
485 if len(actualPrebuiltModuleFile) != 1 {
486 t.Errorf("LOCAL_PREBUILT_MODULE_FILE incorrect len %d", len(actualPrebuiltModuleFile))
487 } else if actualPrebuiltModuleFile[0] != expectedPrebuiltModuleFile {
488 t.Errorf("LOCAL_PREBUILT_MODULE_FILE mismatch, actual: %s, expected: %s", actualPrebuiltModuleFile[0], expectedPrebuiltModuleFile)
489 }
490
491 if len(actualSoongResourceExportPackage) != 1 {
492 t.Errorf("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE incorrect len %d", len(actualSoongResourceExportPackage))
493 } else if actualSoongResourceExportPackage[0] != expectedSoongResourceExportPackage {
494 t.Errorf("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE mismatch, actual: %s, expected: %s", actualSoongResourceExportPackage[0], expectedSoongResourceExportPackage)
495 }
496}
497
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800498func TestAndroidTestImport(t *testing.T) {
Colin Crossaa255532020-07-03 13:18:24 -0700499 ctx, _ := testJava(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800500 android_test_import {
501 name: "foo",
502 apk: "prebuilts/apk/app.apk",
503 presigned: true,
504 data: [
505 "testdata/data",
506 ],
507 }
508 `)
509
510 test := ctx.ModuleForTests("foo", "android_common").Module().(*AndroidTestImport)
511
512 // Check android mks.
Colin Crossaa255532020-07-03 13:18:24 -0700513 entries := android.AndroidMkEntriesForTest(t, ctx, test)[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800514 expected := []string{"tests"}
515 actual := entries.EntryMap["LOCAL_MODULE_TAGS"]
516 if !reflect.DeepEqual(expected, actual) {
517 t.Errorf("Unexpected module tags - expected: %q, actual: %q", expected, actual)
518 }
519 expected = []string{"testdata/data:testdata/data"}
520 actual = entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
521 if !reflect.DeepEqual(expected, actual) {
522 t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual)
523 }
524}
525
526func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) {
527 ctx, _ := testJava(t, `
528 android_test_import {
529 name: "foo",
530 apk: "prebuilts/apk/app.apk",
531 certificate: "cert/new_cert",
532 data: [
533 "testdata/data",
534 ],
535 }
536
537 android_test_import {
538 name: "foo_presigned",
539 apk: "prebuilts/apk/app.apk",
540 presigned: true,
541 data: [
542 "testdata/data",
543 ],
544 }
545 `)
546
547 variant := ctx.ModuleForTests("foo", "android_common")
548 jniRule := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
549 if !strings.HasPrefix(jniRule, "if (zipinfo") {
550 t.Errorf("Unexpected JNI uncompress rule command: " + jniRule)
551 }
552
553 variant = ctx.ModuleForTests("foo_presigned", "android_common")
554 jniRule = variant.Output("jnis-uncompressed/foo_presigned.apk").BuildParams.Rule.String()
555 if jniRule != android.Cp.String() {
556 t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
557 }
558 if variant.MaybeOutput("zip-aligned/foo_presigned.apk").Rule == nil {
559 t.Errorf("Presigned test apk should be aligned")
560 }
561}
562
563func TestAndroidTestImport_Preprocessed(t *testing.T) {
564 ctx, _ := testJava(t, `
565 android_test_import {
566 name: "foo",
567 apk: "prebuilts/apk/app.apk",
568 presigned: true,
569 preprocessed: true,
570 }
571
572 android_test_import {
573 name: "foo_cert",
574 apk: "prebuilts/apk/app.apk",
575 certificate: "cert/new_cert",
576 preprocessed: true,
577 }
578 `)
579
580 testModules := []string{"foo", "foo_cert"}
581 for _, m := range testModules {
582 apkName := m + ".apk"
583 variant := ctx.ModuleForTests(m, "android_common")
584 jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String()
585 if jniRule != android.Cp.String() {
586 t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
587 }
588
589 // Make sure signing and aligning were skipped.
590 if variant.MaybeOutput("signed/"+apkName).Rule != nil {
591 t.Errorf("signing rule shouldn't be included for preprocessed.")
592 }
593 if variant.MaybeOutput("zip-aligned/"+apkName).Rule != nil {
594 t.Errorf("aligning rule shouldn't be for preprocessed")
595 }
596 }
597}