blob: 5de50e794cbdb162a2ba96ac244ebc740d9e8e2f [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 (
Ulya Trafimovich55f72d72021-09-01 14:13:57 +010018 "fmt"
Jaewoong Jungf9b44652020-12-21 12:29:12 -080019 "reflect"
Jaewoong Jungf9b44652020-12-21 12:29:12 -080020 "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.
Spandan Das2069c3f2023-12-06 19:40:24 +000043 if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
44 variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil {
Jaewoong Jungf9b44652020-12-21 12:29:12 -080045 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 }
Wei Li340ee8e2022-03-18 17:33:24 -070055 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"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -080060}
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.
Spandan Das2069c3f2023-12-06 19:40:24 +000077 if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule != nil ||
78 variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule != nil {
Jaewoong Jungf9b44652020-12-21 12:29:12 -080079 t.Errorf("dexpreopt shouldn't have run.")
80 }
Wei Li340ee8e2022-03-18 17:33:24 -070081
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"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -080087}
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.
Spandan Das2069c3f2023-12-06 19:40:24 +0000104 if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
105 variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil {
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800106 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 }
Wei Li340ee8e2022-03-18 17:33:24 -0700115
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"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800121}
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",
Jaewoong Jung25ae8de2021-03-08 17:37:46 -0800129 additional_certificates: [":additional_certificate"],
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800130 lineage: "lineage.bin",
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400131 rotationMinSdkVersion: "32",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800132 }
Jaewoong Jung25ae8de2021-03-08 17:37:46 -0800133
134 android_app_certificate {
135 name: "additional_certificate",
136 certificate: "cert/additional_cert",
137 }
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800138 `)
139
140 variant := ctx.ModuleForTests("foo", "android_common")
141
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800142 signedApk := variant.Output("signed/foo.apk")
Jaewoong Jung25ae8de2021-03-08 17:37:46 -0800143 // 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 }
Rupert Shuttleworth8eab8692021-11-03 10:39:39 -0400151
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)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800157 }
Wei Li340ee8e2022-03-18 17:33:24 -0700158
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"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800164}
165
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800166func 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 }
Wei Li340ee8e2022-03-18 17:33:24 -0700190
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"])
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800196}
197
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800198func 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.
Spandan Das2069c3f2023-12-06 19:40:24 +0000213 if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
214 variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil {
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800215 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 }
Wei Li340ee8e2022-03-18 17:33:24 -0700225
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"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800231}
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 {
Wei Li340ee8e2022-03-18 17:33:24 -0700253 name string
254 aaptPreferredConfig *string
255 aaptPrebuiltDPI []string
256 expected string
257 expectedProvenanceMetaDataArtifactPath string
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800258 }{
259 {
Wei Li340ee8e2022-03-18 17:33:24 -0700260 name: "no preferred",
261 aaptPreferredConfig: nil,
262 aaptPrebuiltDPI: []string{},
263 expected: "verify_uses_libraries/apk/app.apk",
264 expectedProvenanceMetaDataArtifactPath: "prebuilts/apk/app.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800265 },
266 {
Wei Li340ee8e2022-03-18 17:33:24 -0700267 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",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800272 },
273 {
Wei Li340ee8e2022-03-18 17:33:24 -0700274 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",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800279 },
280 {
Wei Li340ee8e2022-03-18 17:33:24 -0700281 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",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800286 },
287 {
Wei Li340ee8e2022-03-18 17:33:24 -0700288 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",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800293 },
294 }
295
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800296 for _, test := range testCases {
Paul Duffinfb8bc952021-03-22 17:31:52 +0000297 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)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800304
Paul Duffinfb8bc952021-03-22 17:31:52 +0000305 variant := result.ModuleForTests("foo", "android_common")
Cole Faust4ec178c2023-01-13 12:03:38 -0800306 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)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800309 }
Wei Li340ee8e2022-03-18 17:33:24 -0700310
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"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800316 }
317}
318
319func TestAndroidAppImport_Filename(t *testing.T) {
Colin Crossaa255532020-07-03 13:18:24 -0700320 ctx, _ := testJava(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800321 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 {
Wei Li340ee8e2022-03-18 17:33:24 -0700336 name string
337 expected string
338 onDevice string
339 expectedArtifactPath string
340 expectedMetaDataPath string
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800341 }{
342 {
Wei Li340ee8e2022-03-18 17:33:24 -0700343 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",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800348 },
349 {
Wei Li340ee8e2022-03-18 17:33:24 -0700350 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",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800355 },
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}
Wei Li598f92d2023-01-04 17:12:24 -0800366 entries := android.AndroidMkEntriesForTest(t, ctx, a)[0]
367 actualValues := entries.EntryMap["LOCAL_INSTALLED_MODULE_STEM"]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800368 if !reflect.DeepEqual(actualValues, expectedValues) {
369 t.Errorf("Incorrect LOCAL_INSTALLED_MODULE_STEM value '%s', expected '%s'",
370 actualValues, expectedValues)
371 }
Wei Li598f92d2023-01-04 17:12:24 -0800372 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "android_app_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
373
Wei Li340ee8e2022-03-18 17:33:24 -0700374 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"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800379 }
380}
381
382func TestAndroidAppImport_ArchVariants(t *testing.T) {
383 // The test config's target arch is ARM64.
384 testCases := []struct {
Wei Li340ee8e2022-03-18 17:33:24 -0700385 name string
386 bp string
387 expected string
388 artifactPath string
389 metaDataPath string
390 installPath string
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800391 }{
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 `,
Wei Li340ee8e2022-03-18 17:33:24 -0700409 expected: "verify_uses_libraries/apk/app_arm64.apk",
410 artifactPath: "prebuilts/apk/app_arm64.apk",
411 installPath: "/system/app/foo/foo.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800412 },
413 {
Cole Faust97494b12024-01-12 14:02:47 -0800414 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 {
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800435 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 `,
Wei Li340ee8e2022-03-18 17:33:24 -0700451 expected: "verify_uses_libraries/apk/app.apk",
452 artifactPath: "prebuilts/apk/app.apk",
453 installPath: "/system/app/foo/foo.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800454 },
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 `,
Wei Li340ee8e2022-03-18 17:33:24 -0700471 expected: "",
472 artifactPath: "prebuilts/apk/app_arm.apk",
473 installPath: "/system/app/foo/foo.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800474 },
Herbert Xue04354ae2024-01-29 13:57:51 +0800475 {
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 },
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800504 }
505
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800506 for _, test := range testCases {
Cole Faust97494b12024-01-12 14:02:47 -0800507 t.Run(test.name, func(t *testing.T) {
508 ctx, _ := testJava(t, test.bp)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800509
Cole Faust97494b12024-01-12 14:02:47 -0800510 variant := ctx.ModuleForTests("foo", "android_common")
511 if test.expected == "" {
512 if variant.Module().Enabled() {
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
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800518 }
Cole Faust97494b12024-01-12 14:02:47 -0800519 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() {
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 })
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800606 }
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() {
633 t.Errorf("prebuilt foo module is disabled")
634 }
635}
636
Spandan Dasd1fac642021-05-18 17:01:41 +0000637func 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 {
Spandan Dasd1fac642021-05-18 17:01:41 +0000653 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 {
Spandan Dasd1fac642021-05-18 17:01:41 +0000676 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
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800688func TestAndroidTestImport(t *testing.T) {
Colin Crossaa255532020-07-03 13:18:24 -0700689 ctx, _ := testJava(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800690 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.
Colin Crossaa255532020-07-03 13:18:24 -0700703 entries := android.AndroidMkEntriesForTest(t, ctx, test)[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800704 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")
Cole Faust4ec178c2023-01-13 12:03:38 -0800738 jniRule := variant.Output("jnis-uncompressed/foo.apk").BuildParams.Rule.String()
739 if jniRule == android.Cp.String() {
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800740 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 }
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800761 `)
762
Cole Faust61585282023-07-14 16:23:39 -0700763 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 }
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800769
Cole Faust61585282023-07-14 16:23:39 -0700770 // 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")
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800776 }
777}
Ulya Trafimovich55f72d72021-09-01 14:13:57 +0100778
Cole Faustccb20f42023-05-04 12:38:24 -0700779func 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")
Cole Faust9c5c09f2023-09-06 16:11:44 -0700791 outputBuildParams := variant.Output(apkName).BuildParams
Cole Faustccb20f42023-05-04 12:38:24 -0700792 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.
Cole Faust9c5c09f2023-09-06 16:11:44 -0700797 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())
Cole Faustccb20f42023-05-04 12:38:24 -0700804 }
805}
Cole Faust2f1da162023-04-17 15:06:56 -0700806
Ulya Trafimovich55f72d72021-09-01 14:13:57 +0100807func 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 {
Ulya Trafimovich0061c0d2021-09-01 15:40:38 +0100854 expect = false
Ulya Trafimovich55f72d72021-09-01 14:13:57 +0100855 } else {
Ulya Trafimovich0061c0d2021-09-01 15:40:38 +0100856 // TODO(b/194504107): shouldn't priv-apps be always uncompressed unless
857 // DONT_UNCOMPRESS_PRIV_APPS_DEXS is true (regardless of unbundling)?
Ulya Trafimovich55f72d72021-09-01 14:13:57 +0100858 // 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}
Colin Crossbc2c8a72022-09-14 12:45:42 -0700877
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}