blob: 00406aa2e33991e11fbab4138d34cd4f8aa7881b [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
141func TestAndroidAppImport_DefaultDevCert(t *testing.T) {
142 ctx, _ := testJava(t, `
143 android_app_import {
144 name: "foo",
145 apk: "prebuilts/apk/app.apk",
146 default_dev_cert: true,
147 dex_preopt: {
148 enabled: true,
149 },
150 }
151 `)
152
153 variant := ctx.ModuleForTests("foo", "android_common")
154
155 // Check dexpreopt outputs.
156 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
157 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
158 t.Errorf("can't find dexpreopt outputs")
159 }
160
161 // Check cert signing flag.
162 signedApk := variant.Output("signed/foo.apk")
163 signingFlag := signedApk.Args["certificates"]
164 expected := "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8"
165 if expected != signingFlag {
166 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
167 }
168}
169
170func TestAndroidAppImport_DpiVariants(t *testing.T) {
171 bp := `
172 android_app_import {
173 name: "foo",
174 apk: "prebuilts/apk/app.apk",
175 dpi_variants: {
176 xhdpi: {
177 apk: "prebuilts/apk/app_xhdpi.apk",
178 },
179 xxhdpi: {
180 apk: "prebuilts/apk/app_xxhdpi.apk",
181 },
182 },
183 presigned: true,
184 dex_preopt: {
185 enabled: true,
186 },
187 }
188 `
189 testCases := []struct {
190 name string
191 aaptPreferredConfig *string
192 aaptPrebuiltDPI []string
193 expected string
194 }{
195 {
196 name: "no preferred",
197 aaptPreferredConfig: nil,
198 aaptPrebuiltDPI: []string{},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000199 expected: "verify_uses_libraries/apk/app.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800200 },
201 {
202 name: "AAPTPreferredConfig matches",
203 aaptPreferredConfig: proptools.StringPtr("xhdpi"),
204 aaptPrebuiltDPI: []string{"xxhdpi", "ldpi"},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000205 expected: "verify_uses_libraries/apk/app_xhdpi.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800206 },
207 {
208 name: "AAPTPrebuiltDPI matches",
209 aaptPreferredConfig: proptools.StringPtr("mdpi"),
210 aaptPrebuiltDPI: []string{"xxhdpi", "xhdpi"},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000211 expected: "verify_uses_libraries/apk/app_xxhdpi.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800212 },
213 {
214 name: "non-first AAPTPrebuiltDPI matches",
215 aaptPreferredConfig: proptools.StringPtr("mdpi"),
216 aaptPrebuiltDPI: []string{"ldpi", "xhdpi"},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000217 expected: "verify_uses_libraries/apk/app_xhdpi.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800218 },
219 {
220 name: "no matches",
221 aaptPreferredConfig: proptools.StringPtr("mdpi"),
222 aaptPrebuiltDPI: []string{"ldpi", "xxxhdpi"},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000223 expected: "verify_uses_libraries/apk/app.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800224 },
225 }
226
227 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
228 for _, test := range testCases {
229 config := testAppConfig(nil, bp, nil)
230 config.TestProductVariables.AAPTPreferredConfig = test.aaptPreferredConfig
231 config.TestProductVariables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
232 ctx := testContext(config)
233
234 run(t, ctx, config)
235
236 variant := ctx.ModuleForTests("foo", "android_common")
237 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
238 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
239 if len(matches) != 2 {
240 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
241 }
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000242 if strings.HasSuffix(matches[1], test.expected) {
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800243 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
244 }
245 }
246}
247
248func TestAndroidAppImport_Filename(t *testing.T) {
Colin Crossaa255532020-07-03 13:18:24 -0700249 ctx, _ := testJava(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800250 android_app_import {
251 name: "foo",
252 apk: "prebuilts/apk/app.apk",
253 presigned: true,
254 }
255
256 android_app_import {
257 name: "bar",
258 apk: "prebuilts/apk/app.apk",
259 presigned: true,
260 filename: "bar_sample.apk"
261 }
262 `)
263
264 testCases := []struct {
265 name string
266 expected string
267 }{
268 {
269 name: "foo",
270 expected: "foo.apk",
271 },
272 {
273 name: "bar",
274 expected: "bar_sample.apk",
275 },
276 }
277
278 for _, test := range testCases {
279 variant := ctx.ModuleForTests(test.name, "android_common")
280 if variant.MaybeOutput(test.expected).Rule == nil {
281 t.Errorf("can't find output named %q - all outputs: %v", test.expected, variant.AllOutputs())
282 }
283
284 a := variant.Module().(*AndroidAppImport)
285 expectedValues := []string{test.expected}
Colin Crossaa255532020-07-03 13:18:24 -0700286 actualValues := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_INSTALLED_MODULE_STEM"]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800287 if !reflect.DeepEqual(actualValues, expectedValues) {
288 t.Errorf("Incorrect LOCAL_INSTALLED_MODULE_STEM value '%s', expected '%s'",
289 actualValues, expectedValues)
290 }
291 }
292}
293
294func TestAndroidAppImport_ArchVariants(t *testing.T) {
295 // The test config's target arch is ARM64.
296 testCases := []struct {
297 name string
298 bp string
299 expected string
300 }{
301 {
302 name: "matching arch",
303 bp: `
304 android_app_import {
305 name: "foo",
306 apk: "prebuilts/apk/app.apk",
307 arch: {
308 arm64: {
309 apk: "prebuilts/apk/app_arm64.apk",
310 },
311 },
312 presigned: true,
313 dex_preopt: {
314 enabled: true,
315 },
316 }
317 `,
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000318 expected: "verify_uses_libraries/apk/app_arm64.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800319 },
320 {
321 name: "no matching arch",
322 bp: `
323 android_app_import {
324 name: "foo",
325 apk: "prebuilts/apk/app.apk",
326 arch: {
327 arm: {
328 apk: "prebuilts/apk/app_arm.apk",
329 },
330 },
331 presigned: true,
332 dex_preopt: {
333 enabled: true,
334 },
335 }
336 `,
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000337 expected: "verify_uses_libraries/apk/app.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800338 },
339 {
340 name: "no matching arch without default",
341 bp: `
342 android_app_import {
343 name: "foo",
344 arch: {
345 arm: {
346 apk: "prebuilts/apk/app_arm.apk",
347 },
348 },
349 presigned: true,
350 dex_preopt: {
351 enabled: true,
352 },
353 }
354 `,
355 expected: "",
356 },
357 }
358
359 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
360 for _, test := range testCases {
361 ctx, _ := testJava(t, test.bp)
362
363 variant := ctx.ModuleForTests("foo", "android_common")
364 if test.expected == "" {
365 if variant.Module().Enabled() {
366 t.Error("module should have been disabled, but wasn't")
367 }
368 continue
369 }
370 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
371 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
372 if len(matches) != 2 {
373 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
374 }
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000375 if strings.HasSuffix(matches[1], test.expected) {
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800376 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
377 }
378 }
379}
380
381func TestAndroidAppImport_overridesDisabledAndroidApp(t *testing.T) {
382 ctx, _ := testJava(t, `
383 android_app {
384 name: "foo",
385 srcs: ["a.java"],
386 enabled: false,
387 }
388
389 android_app_import {
390 name: "foo",
391 apk: "prebuilts/apk/app.apk",
392 certificate: "platform",
393 prefer: true,
394 }
395 `)
396
397 variant := ctx.ModuleForTests("prebuilt_foo", "android_common")
398 a := variant.Module().(*AndroidAppImport)
399 // The prebuilt module should still be enabled and active even if the source-based counterpart
400 // is disabled.
401 if !a.prebuilt.UsePrebuilt() {
402 t.Errorf("prebuilt foo module is not active")
403 }
404 if !a.Enabled() {
405 t.Errorf("prebuilt foo module is disabled")
406 }
407}
408
Bill Peckhama036da92021-01-08 16:09:09 -0800409func TestAndroidAppImport_frameworkRes(t *testing.T) {
Colin Crossaa255532020-07-03 13:18:24 -0700410 ctx, _ := testJava(t, `
Bill Peckhama036da92021-01-08 16:09:09 -0800411 android_app_import {
412 name: "framework-res",
413 certificate: "platform",
414 apk: "package-res.apk",
415 prefer: true,
416 export_package_resources: true,
417 // Disable dexpreopt and verify_uses_libraries check as the app
418 // contains no Java code to be dexpreopted.
419 enforce_uses_libs: false,
420 dex_preopt: {
421 enabled: false,
422 },
423 }
424 `)
425
426 mod := ctx.ModuleForTests("prebuilt_framework-res", "android_common").Module()
427 a := mod.(*AndroidAppImport)
428
429 if !a.preprocessed {
430 t.Errorf("prebuilt framework-res is not preprocessed")
431 }
432
433 expectedInstallPath := buildDir + "/target/product/test_device/system/framework/framework-res.apk"
434
435 if a.dexpreopter.installPath.String() != expectedInstallPath {
436 t.Errorf("prebuilt framework-res installed to incorrect location, actual: %s, expected: %s", a.dexpreopter.installPath, expectedInstallPath)
437
438 }
439
Colin Crossaa255532020-07-03 13:18:24 -0700440 entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
Bill Peckhama036da92021-01-08 16:09:09 -0800441
442 expectedPath := "."
443 // From apk property above, in the root of the source tree.
444 expectedPrebuiltModuleFile := "package-res.apk"
445 // Verify that the apk is preprocessed: The export package is the same
446 // as the prebuilt.
447 expectedSoongResourceExportPackage := expectedPrebuiltModuleFile
448
449 actualPath := entries.EntryMap["LOCAL_PATH"]
450 actualPrebuiltModuleFile := entries.EntryMap["LOCAL_PREBUILT_MODULE_FILE"]
451 actualSoongResourceExportPackage := entries.EntryMap["LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE"]
452
453 if len(actualPath) != 1 {
454 t.Errorf("LOCAL_PATH incorrect len %d", len(actualPath))
455 } else if actualPath[0] != expectedPath {
456 t.Errorf("LOCAL_PATH mismatch, actual: %s, expected: %s", actualPath[0], expectedPath)
457 }
458
459 if len(actualPrebuiltModuleFile) != 1 {
460 t.Errorf("LOCAL_PREBUILT_MODULE_FILE incorrect len %d", len(actualPrebuiltModuleFile))
461 } else if actualPrebuiltModuleFile[0] != expectedPrebuiltModuleFile {
462 t.Errorf("LOCAL_PREBUILT_MODULE_FILE mismatch, actual: %s, expected: %s", actualPrebuiltModuleFile[0], expectedPrebuiltModuleFile)
463 }
464
465 if len(actualSoongResourceExportPackage) != 1 {
466 t.Errorf("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE incorrect len %d", len(actualSoongResourceExportPackage))
467 } else if actualSoongResourceExportPackage[0] != expectedSoongResourceExportPackage {
468 t.Errorf("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE mismatch, actual: %s, expected: %s", actualSoongResourceExportPackage[0], expectedSoongResourceExportPackage)
469 }
470}
471
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800472func TestAndroidTestImport(t *testing.T) {
Colin Crossaa255532020-07-03 13:18:24 -0700473 ctx, _ := testJava(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800474 android_test_import {
475 name: "foo",
476 apk: "prebuilts/apk/app.apk",
477 presigned: true,
478 data: [
479 "testdata/data",
480 ],
481 }
482 `)
483
484 test := ctx.ModuleForTests("foo", "android_common").Module().(*AndroidTestImport)
485
486 // Check android mks.
Colin Crossaa255532020-07-03 13:18:24 -0700487 entries := android.AndroidMkEntriesForTest(t, ctx, test)[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800488 expected := []string{"tests"}
489 actual := entries.EntryMap["LOCAL_MODULE_TAGS"]
490 if !reflect.DeepEqual(expected, actual) {
491 t.Errorf("Unexpected module tags - expected: %q, actual: %q", expected, actual)
492 }
493 expected = []string{"testdata/data:testdata/data"}
494 actual = entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
495 if !reflect.DeepEqual(expected, actual) {
496 t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual)
497 }
498}
499
500func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) {
501 ctx, _ := testJava(t, `
502 android_test_import {
503 name: "foo",
504 apk: "prebuilts/apk/app.apk",
505 certificate: "cert/new_cert",
506 data: [
507 "testdata/data",
508 ],
509 }
510
511 android_test_import {
512 name: "foo_presigned",
513 apk: "prebuilts/apk/app.apk",
514 presigned: true,
515 data: [
516 "testdata/data",
517 ],
518 }
519 `)
520
521 variant := ctx.ModuleForTests("foo", "android_common")
522 jniRule := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
523 if !strings.HasPrefix(jniRule, "if (zipinfo") {
524 t.Errorf("Unexpected JNI uncompress rule command: " + jniRule)
525 }
526
527 variant = ctx.ModuleForTests("foo_presigned", "android_common")
528 jniRule = variant.Output("jnis-uncompressed/foo_presigned.apk").BuildParams.Rule.String()
529 if jniRule != android.Cp.String() {
530 t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
531 }
532 if variant.MaybeOutput("zip-aligned/foo_presigned.apk").Rule == nil {
533 t.Errorf("Presigned test apk should be aligned")
534 }
535}
536
537func TestAndroidTestImport_Preprocessed(t *testing.T) {
538 ctx, _ := testJava(t, `
539 android_test_import {
540 name: "foo",
541 apk: "prebuilts/apk/app.apk",
542 presigned: true,
543 preprocessed: true,
544 }
545
546 android_test_import {
547 name: "foo_cert",
548 apk: "prebuilts/apk/app.apk",
549 certificate: "cert/new_cert",
550 preprocessed: true,
551 }
552 `)
553
554 testModules := []string{"foo", "foo_cert"}
555 for _, m := range testModules {
556 apkName := m + ".apk"
557 variant := ctx.ModuleForTests(m, "android_common")
558 jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String()
559 if jniRule != android.Cp.String() {
560 t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
561 }
562
563 // Make sure signing and aligning were skipped.
564 if variant.MaybeOutput("signed/"+apkName).Rule != nil {
565 t.Errorf("signing rule shouldn't be included for preprocessed.")
566 }
567 if variant.MaybeOutput("zip-aligned/"+apkName).Rule != nil {
568 t.Errorf("aligning rule shouldn't be for preprocessed")
569 }
570 }
571}