• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/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	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/oat/arm64/package.vdex").Rule != nil ||
78		variant.MaybeOutput("dexpreopt/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/oat/arm64/package.vdex").Rule == nil ||
105		variant.MaybeOutput("dexpreopt/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/oat/arm64/package.vdex").Rule == nil ||
214		variant.MaybeOutput("dexpreopt/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: "no matching arch",
415			bp: `
416				android_app_import {
417					name: "foo",
418					apk: "prebuilts/apk/app.apk",
419					arch: {
420						arm: {
421							apk: "prebuilts/apk/app_arm.apk",
422						},
423					},
424					presigned: true,
425					dex_preopt: {
426						enabled: true,
427					},
428				}
429			`,
430			expected:     "verify_uses_libraries/apk/app.apk",
431			artifactPath: "prebuilts/apk/app.apk",
432			installPath:  "/system/app/foo/foo.apk",
433		},
434		{
435			name: "no matching arch without default",
436			bp: `
437				android_app_import {
438					name: "foo",
439					arch: {
440						arm: {
441							apk: "prebuilts/apk/app_arm.apk",
442						},
443					},
444					presigned: true,
445					dex_preopt: {
446						enabled: true,
447					},
448				}
449			`,
450			expected:     "",
451			artifactPath: "prebuilts/apk/app_arm.apk",
452			installPath:  "/system/app/foo/foo.apk",
453		},
454	}
455
456	for _, test := range testCases {
457		ctx, _ := testJava(t, test.bp)
458
459		variant := ctx.ModuleForTests("foo", "android_common")
460		if test.expected == "" {
461			if variant.Module().Enabled() {
462				t.Error("module should have been disabled, but wasn't")
463			}
464			rule := variant.MaybeRule("genProvenanceMetaData")
465			android.AssertDeepEquals(t, "Provenance metadata is not empty", android.TestingBuildParams{}, rule)
466			continue
467		}
468		input := variant.Output("jnis-uncompressed/foo.apk").Input.String()
469		if strings.HasSuffix(input, test.expected) {
470			t.Errorf("wrong src apk, expected: %q got: %q", test.expected, input)
471		}
472		rule := variant.Rule("genProvenanceMetaData")
473		android.AssertStringEquals(t, "Invalid input", test.artifactPath, rule.Inputs[0].String())
474		android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String())
475		android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"])
476		android.AssertStringEquals(t, "Invalid args", test.installPath, rule.Args["install_path"])
477	}
478}
479
480func TestAndroidAppImport_overridesDisabledAndroidApp(t *testing.T) {
481	ctx, _ := testJava(t, `
482		android_app {
483			name: "foo",
484			srcs: ["a.java"],
485			enabled: false,
486		}
487
488 		android_app_import {
489			name: "foo",
490			apk: "prebuilts/apk/app.apk",
491			certificate: "platform",
492			prefer: true,
493		}
494		`)
495
496	variant := ctx.ModuleForTests("prebuilt_foo", "android_common")
497	a := variant.Module().(*AndroidAppImport)
498	// The prebuilt module should still be enabled and active even if the source-based counterpart
499	// is disabled.
500	if !a.prebuilt.UsePrebuilt() {
501		t.Errorf("prebuilt foo module is not active")
502	}
503	if !a.Enabled() {
504		t.Errorf("prebuilt foo module is disabled")
505	}
506}
507
508func TestAndroidAppImport_relativeInstallPath(t *testing.T) {
509	bp := `
510		android_app_import {
511			name: "no_relative_install_path",
512			apk: "prebuilts/apk/app.apk",
513			presigned: true,
514		}
515
516		android_app_import {
517			name: "relative_install_path",
518			apk: "prebuilts/apk/app.apk",
519			presigned: true,
520			relative_install_path: "my/path",
521		}
522
523		android_app_import {
524			name: "privileged_relative_install_path",
525			apk: "prebuilts/apk/app.apk",
526			presigned: true,
527			privileged: true,
528			relative_install_path: "my/path"
529		}
530		`
531	testCases := []struct {
532		name                string
533		expectedInstallPath string
534		errorMessage        string
535	}{
536		{
537			name:                "no_relative_install_path",
538			expectedInstallPath: "out/soong/target/product/test_device/system/app/no_relative_install_path/no_relative_install_path.apk",
539			errorMessage:        "Install path is not correct when relative_install_path is missing",
540		},
541		{
542			name:                "relative_install_path",
543			expectedInstallPath: "out/soong/target/product/test_device/system/app/my/path/relative_install_path/relative_install_path.apk",
544			errorMessage:        "Install path is not correct for app when relative_install_path is present",
545		},
546		{
547			name:                "privileged_relative_install_path",
548			expectedInstallPath: "out/soong/target/product/test_device/system/priv-app/my/path/privileged_relative_install_path/privileged_relative_install_path.apk",
549			errorMessage:        "Install path is not correct for privileged app when relative_install_path is present",
550		},
551	}
552	for _, testCase := range testCases {
553		ctx, _ := testJava(t, bp)
554		mod := ctx.ModuleForTests(testCase.name, "android_common").Module().(*AndroidAppImport)
555		android.AssertPathRelativeToTopEquals(t, testCase.errorMessage, testCase.expectedInstallPath, mod.installPath)
556	}
557}
558
559func TestAndroidTestImport(t *testing.T) {
560	ctx, _ := testJava(t, `
561		android_test_import {
562			name: "foo",
563			apk: "prebuilts/apk/app.apk",
564			presigned: true,
565			data: [
566				"testdata/data",
567			],
568		}
569		`)
570
571	test := ctx.ModuleForTests("foo", "android_common").Module().(*AndroidTestImport)
572
573	// Check android mks.
574	entries := android.AndroidMkEntriesForTest(t, ctx, test)[0]
575	expected := []string{"tests"}
576	actual := entries.EntryMap["LOCAL_MODULE_TAGS"]
577	if !reflect.DeepEqual(expected, actual) {
578		t.Errorf("Unexpected module tags - expected: %q, actual: %q", expected, actual)
579	}
580	expected = []string{"testdata/data:testdata/data"}
581	actual = entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
582	if !reflect.DeepEqual(expected, actual) {
583		t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual)
584	}
585}
586
587func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) {
588	ctx, _ := testJava(t, `
589		android_test_import {
590			name: "foo",
591			apk: "prebuilts/apk/app.apk",
592			certificate: "cert/new_cert",
593			data: [
594				"testdata/data",
595			],
596		}
597
598		android_test_import {
599			name: "foo_presigned",
600			apk: "prebuilts/apk/app.apk",
601			presigned: true,
602			data: [
603				"testdata/data",
604			],
605		}
606		`)
607
608	variant := ctx.ModuleForTests("foo", "android_common")
609	jniRule := variant.Output("jnis-uncompressed/foo.apk").BuildParams.Rule.String()
610	if jniRule == android.Cp.String() {
611		t.Errorf("Unexpected JNI uncompress rule command: " + jniRule)
612	}
613
614	variant = ctx.ModuleForTests("foo_presigned", "android_common")
615	jniRule = variant.Output("jnis-uncompressed/foo_presigned.apk").BuildParams.Rule.String()
616	if jniRule != android.Cp.String() {
617		t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
618	}
619	if variant.MaybeOutput("zip-aligned/foo_presigned.apk").Rule == nil {
620		t.Errorf("Presigned test apk should be aligned")
621	}
622}
623
624func TestAndroidTestImport_Preprocessed(t *testing.T) {
625	ctx, _ := testJava(t, `
626		android_test_import {
627			name: "foo",
628			apk: "prebuilts/apk/app.apk",
629			presigned: true,
630			preprocessed: true,
631		}
632
633		android_test_import {
634			name: "foo_cert",
635			apk: "prebuilts/apk/app.apk",
636			certificate: "cert/new_cert",
637			preprocessed: true,
638		}
639		`)
640
641	testModules := []string{"foo", "foo_cert"}
642	for _, m := range testModules {
643		apkName := m + ".apk"
644		variant := ctx.ModuleForTests(m, "android_common")
645		jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String()
646		if jniRule != android.Cp.String() {
647			t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
648		}
649
650		// Make sure signing and aligning were skipped.
651		if variant.MaybeOutput("signed/"+apkName).Rule != nil {
652			t.Errorf("signing rule shouldn't be included for preprocessed.")
653		}
654		if variant.MaybeOutput("zip-aligned/"+apkName).Rule != nil {
655			t.Errorf("aligning rule shouldn't be for preprocessed")
656		}
657	}
658}
659
660func TestAndroidTestImport_UncompressDex(t *testing.T) {
661	testCases := []struct {
662		name string
663		bp   string
664	}{
665		{
666			name: "normal",
667			bp: `
668				android_app_import {
669					name: "foo",
670					presigned: true,
671					apk: "prebuilts/apk/app.apk",
672				}
673			`,
674		},
675		{
676			name: "privileged",
677			bp: `
678				android_app_import {
679					name: "foo",
680					presigned: true,
681					privileged: true,
682					apk: "prebuilts/apk/app.apk",
683				}
684			`,
685		},
686	}
687
688	test := func(t *testing.T, bp string, unbundled bool, dontUncompressPrivAppDexs bool) {
689		t.Helper()
690
691		result := android.GroupFixturePreparers(
692			prepareForJavaTest,
693			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
694				if unbundled {
695					variables.Unbundled_build = proptools.BoolPtr(true)
696				}
697				variables.UncompressPrivAppDex = proptools.BoolPtr(!dontUncompressPrivAppDexs)
698			}),
699		).RunTestWithBp(t, bp)
700
701		foo := result.ModuleForTests("foo", "android_common")
702		actual := foo.MaybeRule("uncompress-dex").Rule != nil
703
704		expect := !unbundled
705		if strings.Contains(bp, "privileged: true") {
706			if dontUncompressPrivAppDexs {
707				expect = false
708			} else {
709				// TODO(b/194504107): shouldn't priv-apps be always uncompressed unless
710				// DONT_UNCOMPRESS_PRIV_APPS_DEXS is true (regardless of unbundling)?
711				// expect = true
712			}
713		}
714
715		android.AssertBoolEquals(t, "uncompress dex", expect, actual)
716	}
717
718	for _, unbundled := range []bool{false, true} {
719		for _, dontUncompressPrivAppDexs := range []bool{false, true} {
720			for _, tt := range testCases {
721				name := fmt.Sprintf("%s,unbundled:%t,dontUncompressPrivAppDexs:%t",
722					tt.name, unbundled, dontUncompressPrivAppDexs)
723				t.Run(name, func(t *testing.T) {
724					test(t, tt.bp, unbundled, dontUncompressPrivAppDexs)
725				})
726			}
727		}
728	}
729}
730
731func TestAppImportMissingCertificateAllowMissingDependencies(t *testing.T) {
732	result := android.GroupFixturePreparers(
733		PrepareForTestWithJavaDefaultModules,
734		android.PrepareForTestWithAllowMissingDependencies,
735		android.PrepareForTestWithAndroidMk,
736	).RunTestWithBp(t, `
737		android_app_import {
738			name: "foo",
739			apk: "a.apk",
740			certificate: ":missing_certificate",
741		}`)
742
743	foo := result.ModuleForTests("foo", "android_common")
744	fooApk := foo.Output("signed/foo.apk")
745	if fooApk.Rule != android.ErrorRule {
746		t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String())
747	}
748	android.AssertStringDoesContain(t, "expected error rule message", fooApk.Args["error"], "missing dependencies: missing_certificate\n")
749}
750