• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 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	"path/filepath"
20	"reflect"
21	"sort"
22	"strings"
23	"testing"
24
25	"github.com/google/blueprint/proptools"
26
27	"android/soong/android"
28	"android/soong/cc"
29	"android/soong/dexpreopt"
30)
31
32// testApp runs tests using the prepareForJavaTest
33//
34// See testJava for an explanation as to how to stop using this deprecated method.
35//
36// deprecated
37func testApp(t *testing.T, bp string) *android.TestContext {
38	t.Helper()
39	result := prepareForJavaTest.RunTestWithBp(t, bp)
40	return result.TestContext
41}
42
43func TestApp(t *testing.T) {
44	resourceFiles := []string{
45		"res/layout/layout.xml",
46		"res/values/strings.xml",
47		"res/values-en-rUS/strings.xml",
48	}
49
50	compiledResourceFiles := []string{
51		"aapt2/res/layout_layout.xml.flat",
52		"aapt2/res/values_strings.arsc.flat",
53		"aapt2/res/values-en-rUS_strings.arsc.flat",
54	}
55
56	for _, moduleType := range []string{"android_app", "android_library"} {
57		t.Run(moduleType, func(t *testing.T) {
58			result := android.GroupFixturePreparers(
59				prepareForJavaTest,
60				android.FixtureModifyMockFS(func(fs android.MockFS) {
61					for _, file := range resourceFiles {
62						fs[file] = nil
63					}
64				}),
65			).RunTestWithBp(t, moduleType+` {
66					name: "foo",
67					srcs: ["a.java"],
68					sdk_version: "current"
69				}
70			`)
71
72			foo := result.ModuleForTests("foo", "android_common")
73
74			var expectedLinkImplicits []string
75
76			manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml")
77			expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String())
78
79			frameworkRes := result.ModuleForTests("framework-res", "android_common")
80			expectedLinkImplicits = append(expectedLinkImplicits,
81				frameworkRes.Output("package-res.apk").Output.String())
82
83			// Test the mapping from input files to compiled output file names
84			compile := foo.Output(compiledResourceFiles[0])
85			android.AssertDeepEquals(t, "aapt2 compile inputs", resourceFiles, compile.Inputs.Strings())
86
87			compiledResourceOutputs := compile.Outputs.Strings()
88			sort.Strings(compiledResourceOutputs)
89
90			expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...)
91
92			list := foo.Output("aapt2/res.list")
93			expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
94
95			// Check that the link rule uses
96			res := result.ModuleForTests("foo", "android_common").Output("package-res.apk")
97			android.AssertDeepEquals(t, "aapt2 link implicits", expectedLinkImplicits, res.Implicits.Strings())
98		})
99	}
100}
101
102func TestAppSplits(t *testing.T) {
103	ctx := testApp(t, `
104				android_app {
105					name: "foo",
106					srcs: ["a.java"],
107					package_splits: ["v4", "v7,hdpi"],
108					sdk_version: "current"
109				}`)
110
111	foo := ctx.ModuleForTests("foo", "android_common")
112
113	expectedOutputs := []string{
114		"out/soong/.intermediates/foo/android_common/foo.apk",
115		"out/soong/.intermediates/foo/android_common/foo_v4.apk",
116		"out/soong/.intermediates/foo/android_common/foo_v7_hdpi.apk",
117	}
118	for _, expectedOutput := range expectedOutputs {
119		foo.Output(expectedOutput)
120	}
121
122	outputFiles, err := foo.Module().(*AndroidApp).OutputFiles("")
123	if err != nil {
124		t.Fatal(err)
125	}
126	android.AssertPathsRelativeToTopEquals(t, `OutputFiles("")`, expectedOutputs, outputFiles)
127}
128
129func TestPlatformAPIs(t *testing.T) {
130	testJava(t, `
131		android_app {
132			name: "foo",
133			srcs: ["a.java"],
134			platform_apis: true,
135		}
136	`)
137
138	testJava(t, `
139		android_app {
140			name: "foo",
141			srcs: ["a.java"],
142			sdk_version: "current",
143		}
144	`)
145
146	testJavaError(t, "This module has conflicting settings. sdk_version is empty, which means that this module is build against platform APIs. However platform_apis is not set to true", `
147		android_app {
148			name: "bar",
149			srcs: ["b.java"],
150		}
151	`)
152
153	testJavaError(t, "This module has conflicting settings. sdk_version is not empty, which means this module cannot use platform APIs. However platform_apis is set to true.", `
154		android_app {
155			name: "bar",
156			srcs: ["b.java"],
157			sdk_version: "system_current",
158			platform_apis: true,
159		}
160	`)
161}
162
163func TestAndroidAppLinkType(t *testing.T) {
164	testJava(t, `
165		android_app {
166			name: "foo",
167			srcs: ["a.java"],
168			libs: ["bar"],
169			static_libs: ["baz"],
170			platform_apis: true,
171		}
172
173		java_library {
174			name: "bar",
175			sdk_version: "current",
176			srcs: ["b.java"],
177		}
178
179		android_library {
180			name: "baz",
181			sdk_version: "system_current",
182			srcs: ["c.java"],
183		}
184	`)
185
186	testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
187		android_app {
188			name: "foo",
189			srcs: ["a.java"],
190			libs: ["bar"],
191			sdk_version: "current",
192			static_libs: ["baz"],
193		}
194
195		java_library {
196			name: "bar",
197			sdk_version: "current",
198			srcs: ["b.java"],
199		}
200
201		android_library {
202			name: "baz",
203			sdk_version: "system_current",
204			srcs: ["c.java"],
205		}
206	`)
207
208	testJava(t, `
209		android_app {
210			name: "foo",
211			srcs: ["a.java"],
212			libs: ["bar"],
213			sdk_version: "system_current",
214			static_libs: ["baz"],
215		}
216
217		java_library {
218			name: "bar",
219			sdk_version: "current",
220			srcs: ["b.java"],
221		}
222
223		android_library {
224			name: "baz",
225			sdk_version: "system_current",
226			srcs: ["c.java"],
227		}
228	`)
229
230	testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
231		android_app {
232			name: "foo",
233			srcs: ["a.java"],
234			libs: ["bar"],
235			sdk_version: "system_current",
236			static_libs: ["baz"],
237		}
238
239		java_library {
240			name: "bar",
241			sdk_version: "current",
242			srcs: ["b.java"],
243		}
244
245		android_library {
246			name: "baz",
247			srcs: ["c.java"],
248		}
249	`)
250}
251
252func TestUpdatableApps(t *testing.T) {
253	testCases := []struct {
254		name          string
255		bp            string
256		expectedError string
257	}{
258		{
259			name: "Stable public SDK",
260			bp: `android_app {
261					name: "foo",
262					srcs: ["a.java"],
263					sdk_version: "29",
264					min_sdk_version: "29",
265					updatable: true,
266				}`,
267		},
268		{
269			name: "Stable system SDK",
270			bp: `android_app {
271					name: "foo",
272					srcs: ["a.java"],
273					sdk_version: "system_29",
274					min_sdk_version: "29",
275					updatable: true,
276				}`,
277		},
278		{
279			name: "Current public SDK",
280			bp: `android_app {
281					name: "foo",
282					srcs: ["a.java"],
283					sdk_version: "current",
284					min_sdk_version: "29",
285					updatable: true,
286				}`,
287		},
288		{
289			name: "Current system SDK",
290			bp: `android_app {
291					name: "foo",
292					srcs: ["a.java"],
293					sdk_version: "system_current",
294					min_sdk_version: "29",
295					updatable: true,
296				}`,
297		},
298		{
299			name: "Current module SDK",
300			bp: `android_app {
301					name: "foo",
302					srcs: ["a.java"],
303					sdk_version: "module_current",
304					min_sdk_version: "29",
305					updatable: true,
306				}`,
307		},
308		{
309			name: "Current core SDK",
310			bp: `android_app {
311					name: "foo",
312					srcs: ["a.java"],
313					sdk_version: "core_current",
314					min_sdk_version: "29",
315					updatable: true,
316				}`,
317		},
318		{
319			name: "No Platform APIs",
320			bp: `android_app {
321					name: "foo",
322					srcs: ["a.java"],
323					platform_apis: true,
324					min_sdk_version: "29",
325					updatable: true,
326				}`,
327			expectedError: "Updatable apps must use stable SDKs",
328		},
329		{
330			name: "No Core Platform APIs",
331			bp: `android_app {
332					name: "foo",
333					srcs: ["a.java"],
334					sdk_version: "core_platform",
335					min_sdk_version: "29",
336					updatable: true,
337				}`,
338			expectedError: "Updatable apps must use stable SDKs",
339		},
340		{
341			name: "No unspecified APIs",
342			bp: `android_app {
343					name: "foo",
344					srcs: ["a.java"],
345					updatable: true,
346					min_sdk_version: "29",
347				}`,
348			expectedError: "Updatable apps must use stable SDK",
349		},
350		{
351			name: "Must specify min_sdk_version",
352			bp: `android_app {
353					name: "app_without_min_sdk_version",
354					srcs: ["a.java"],
355					sdk_version: "29",
356					updatable: true,
357				}`,
358			expectedError: "updatable apps must set min_sdk_version.",
359		},
360	}
361
362	for _, test := range testCases {
363		t.Run(test.name, func(t *testing.T) {
364			errorHandler := android.FixtureExpectsNoErrors
365			if test.expectedError != "" {
366				errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError)
367			}
368			android.GroupFixturePreparers(
369				prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{
370					"29": {"foo"},
371				})).
372				ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, test.bp)
373		})
374	}
375}
376
377func TestUpdatableApps_TransitiveDepsShouldSetMinSdkVersion(t *testing.T) {
378	testJavaError(t, `module "bar".*: should support min_sdk_version\(29\)`, cc.GatherRequiredDepsForTest(android.Android)+`
379		android_app {
380			name: "foo",
381			srcs: ["a.java"],
382			updatable: true,
383			sdk_version: "current",
384			min_sdk_version: "29",
385			static_libs: ["bar"],
386		}
387
388		java_library {
389			name: "bar",
390			sdk_version: "current",
391		}
392	`)
393}
394
395func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion(t *testing.T) {
396	testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
397		android_app {
398			name: "foo",
399			srcs: ["a.java"],
400			updatable: true,
401			sdk_version: "current",
402			min_sdk_version: "current",
403			jni_libs: ["libjni"],
404		}
405
406		cc_library {
407			name: "libjni",
408			stl: "none",
409			system_shared_libs: [],
410			sdk_version: "current",
411		}
412	`)
413}
414
415func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) {
416	bp := cc.GatherRequiredDepsForTest(android.Android) + `
417		android_app {
418			name: "foo",
419			srcs: ["a.java"],
420			updatable: true,
421			sdk_version: "current",
422			min_sdk_version: "29",
423			jni_libs: ["libjni"],
424		}
425
426		cc_library {
427			name: "libjni",
428			stl: "none",
429			system_shared_libs: [],
430			sdk_version: "current",
431			min_sdk_version: "29",
432		}
433	`
434	fs := map[string][]byte{
435		"prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o": nil,
436		"prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtend_so.o":   nil,
437		"prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtbegin_so.o":   nil,
438		"prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtend_so.o":     nil,
439	}
440
441	ctx, _ := testJavaWithFS(t, bp, fs)
442
443	inputs := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits
444	var crtbeginFound, crtendFound bool
445	expectedCrtBegin := ctx.ModuleForTests("crtbegin_so",
446		"android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
447	expectedCrtEnd := ctx.ModuleForTests("crtend_so",
448		"android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
449	implicits := []string{}
450	for _, input := range inputs {
451		implicits = append(implicits, input.String())
452		if strings.HasSuffix(input.String(), expectedCrtBegin.String()) {
453			crtbeginFound = true
454		} else if strings.HasSuffix(input.String(), expectedCrtEnd.String()) {
455			crtendFound = true
456		}
457	}
458	if !crtbeginFound {
459		t.Error(fmt.Sprintf(
460			"expected implicit with suffix %q, have the following implicits:\n%s",
461			expectedCrtBegin, strings.Join(implicits, "\n")))
462	}
463	if !crtendFound {
464		t.Error(fmt.Sprintf(
465			"expected implicit with suffix %q, have the following implicits:\n%s",
466			expectedCrtEnd, strings.Join(implicits, "\n")))
467	}
468}
469
470func TestUpdatableApps_ErrorIfJniLibDoesntSupportMinSdkVersion(t *testing.T) {
471	bp := cc.GatherRequiredDepsForTest(android.Android) + `
472		android_app {
473			name: "foo",
474			srcs: ["a.java"],
475			updatable: true,
476			sdk_version: "current",
477			min_sdk_version: "29",  // this APK should support 29
478			jni_libs: ["libjni"],
479		}
480
481		cc_library {
482			name: "libjni",
483			stl: "none",
484			sdk_version: "current",
485			min_sdk_version: "current",
486		}
487	`
488	testJavaError(t, `"libjni" .*: min_sdk_version\(current\) is higher than min_sdk_version\(29\)`, bp)
489}
490
491func TestUpdatableApps_ErrorIfDepMinSdkVersionIsHigher(t *testing.T) {
492	bp := cc.GatherRequiredDepsForTest(android.Android) + `
493		android_app {
494			name: "foo",
495			srcs: ["a.java"],
496			updatable: true,
497			sdk_version: "current",
498			min_sdk_version: "29",  // this APK should support 29
499			jni_libs: ["libjni"],
500		}
501
502		cc_library {
503			name: "libjni",
504			stl: "none",
505			shared_libs: ["libbar"],
506			system_shared_libs: [],
507			sdk_version: "27",
508			min_sdk_version: "27",
509		}
510
511		cc_library {
512			name: "libbar",
513			stl: "none",
514			system_shared_libs: [],
515			sdk_version: "current",
516			min_sdk_version: "current",
517		}
518	`
519	testJavaError(t, `"libjni" .*: links "libbar" built against newer API version "current"`, bp)
520}
521
522func TestResourceDirs(t *testing.T) {
523	testCases := []struct {
524		name      string
525		prop      string
526		resources []string
527	}{
528		{
529			name:      "no resource_dirs",
530			prop:      "",
531			resources: []string{"res/res/values/strings.xml"},
532		},
533		{
534			name:      "resource_dirs",
535			prop:      `resource_dirs: ["res"]`,
536			resources: []string{"res/res/values/strings.xml"},
537		},
538		{
539			name:      "empty resource_dirs",
540			prop:      `resource_dirs: []`,
541			resources: nil,
542		},
543	}
544
545	fs := android.MockFS{
546		"res/res/values/strings.xml": nil,
547	}
548
549	bp := `
550			android_app {
551				name: "foo",
552				sdk_version: "current",
553				%s
554			}
555		`
556
557	for _, testCase := range testCases {
558		t.Run(testCase.name, func(t *testing.T) {
559			result := android.GroupFixturePreparers(
560				PrepareForTestWithJavaDefaultModules,
561				PrepareForTestWithOverlayBuildComponents,
562				fs.AddToFixture(),
563			).RunTestWithBp(t, fmt.Sprintf(bp, testCase.prop))
564
565			module := result.ModuleForTests("foo", "android_common")
566			resourceList := module.MaybeOutput("aapt2/res.list")
567
568			var resources []string
569			if resourceList.Rule != nil {
570				for _, compiledResource := range resourceList.Inputs.Strings() {
571					resources = append(resources, module.Output(compiledResource).Inputs.Strings()...)
572				}
573			}
574
575			android.AssertDeepEquals(t, "resource files", testCase.resources, resources)
576		})
577	}
578}
579
580func TestLibraryAssets(t *testing.T) {
581	bp := `
582			android_app {
583				name: "foo",
584				sdk_version: "current",
585				static_libs: ["lib1", "lib2", "lib3"],
586			}
587
588			android_library {
589				name: "lib1",
590				sdk_version: "current",
591				asset_dirs: ["assets_a"],
592			}
593
594			android_library {
595				name: "lib2",
596				sdk_version: "current",
597			}
598
599			android_library {
600				name: "lib3",
601				sdk_version: "current",
602				static_libs: ["lib4"],
603			}
604
605			android_library {
606				name: "lib4",
607				sdk_version: "current",
608				asset_dirs: ["assets_b"],
609			}
610		`
611
612	testCases := []struct {
613		name          string
614		assetFlag     string
615		assetPackages []string
616	}{
617		{
618			name: "foo",
619			// lib1 has its own asset. lib3 doesn't have any, but provides lib4's transitively.
620			assetPackages: []string{
621				"out/soong/.intermediates/foo/android_common/aapt2/package-res.apk",
622				"out/soong/.intermediates/lib1/android_common/assets.zip",
623				"out/soong/.intermediates/lib3/android_common/assets.zip",
624			},
625		},
626		{
627			name:      "lib1",
628			assetFlag: "-A assets_a",
629		},
630		{
631			name: "lib2",
632		},
633		{
634			name: "lib3",
635			assetPackages: []string{
636				"out/soong/.intermediates/lib3/android_common/aapt2/package-res.apk",
637				"out/soong/.intermediates/lib4/android_common/assets.zip",
638			},
639		},
640		{
641			name:      "lib4",
642			assetFlag: "-A assets_b",
643		},
644	}
645	ctx := testApp(t, bp)
646
647	for _, test := range testCases {
648		t.Run(test.name, func(t *testing.T) {
649			m := ctx.ModuleForTests(test.name, "android_common")
650
651			// Check asset flag in aapt2 link flags
652			var aapt2link android.TestingBuildParams
653			if len(test.assetPackages) > 0 {
654				aapt2link = m.Output("aapt2/package-res.apk")
655			} else {
656				aapt2link = m.Output("package-res.apk")
657			}
658			aapt2link = aapt2link
659			aapt2Flags := aapt2link.Args["flags"]
660			if test.assetFlag != "" {
661				android.AssertStringDoesContain(t, "asset flag", aapt2Flags, test.assetFlag)
662			} else {
663				android.AssertStringDoesNotContain(t, "aapt2 link flags", aapt2Flags, " -A ")
664			}
665
666			// Check asset merge rule.
667			if len(test.assetPackages) > 0 {
668				mergeAssets := m.Output("package-res.apk")
669				android.AssertPathsRelativeToTopEquals(t, "mergeAssets inputs", test.assetPackages, mergeAssets.Inputs)
670			}
671		})
672	}
673}
674
675func TestAppJavaResources(t *testing.T) {
676	bp := `
677			android_app {
678				name: "foo",
679				sdk_version: "current",
680				java_resources: ["resources/a"],
681				srcs: ["a.java"],
682			}
683
684			android_app {
685				name: "bar",
686				sdk_version: "current",
687				java_resources: ["resources/a"],
688			}
689		`
690
691	ctx := testApp(t, bp)
692
693	foo := ctx.ModuleForTests("foo", "android_common")
694	fooResources := foo.Output("res/foo.jar")
695	fooDexJar := foo.Output("dex-withres/foo.jar")
696	fooDexJarAligned := foo.Output("dex-withres-aligned/foo.jar")
697	fooApk := foo.Rule("combineApk")
698
699	if g, w := fooDexJar.Inputs.Strings(), fooResources.Output.String(); !android.InList(w, g) {
700		t.Errorf("expected resource jar %q in foo dex jar inputs %q", w, g)
701	}
702
703	if g, w := fooDexJarAligned.Input.String(), fooDexJar.Output.String(); g != w {
704		t.Errorf("expected dex jar %q in foo aligned dex jar inputs %q", w, g)
705	}
706
707	if g, w := fooApk.Inputs.Strings(), fooDexJarAligned.Output.String(); !android.InList(w, g) {
708		t.Errorf("expected aligned dex jar %q in foo apk inputs %q", w, g)
709	}
710
711	bar := ctx.ModuleForTests("bar", "android_common")
712	barResources := bar.Output("res/bar.jar")
713	barApk := bar.Rule("combineApk")
714
715	if g, w := barApk.Inputs.Strings(), barResources.Output.String(); !android.InList(w, g) {
716		t.Errorf("expected resources jar %q in bar apk inputs %q", w, g)
717	}
718}
719
720func TestAndroidResources(t *testing.T) {
721	testCases := []struct {
722		name                       string
723		enforceRROTargets          []string
724		enforceRROExcludedOverlays []string
725		resourceFiles              map[string][]string
726		overlayFiles               map[string][]string
727		rroDirs                    map[string][]string
728	}{
729		{
730			name:                       "no RRO",
731			enforceRROTargets:          nil,
732			enforceRROExcludedOverlays: nil,
733			resourceFiles: map[string][]string{
734				"foo":  nil,
735				"bar":  {"bar/res/res/values/strings.xml"},
736				"lib":  nil,
737				"lib2": {"lib2/res/res/values/strings.xml"},
738			},
739			overlayFiles: map[string][]string{
740				"foo": {
741					"out/soong/.intermediates/lib2/android_common/package-res.apk",
742					"out/soong/.intermediates/lib/android_common/package-res.apk",
743					"out/soong/.intermediates/lib3/android_common/package-res.apk",
744					"foo/res/res/values/strings.xml",
745					"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
746					"device/vendor/blah/overlay/foo/res/values/strings.xml",
747					"product/vendor/blah/overlay/foo/res/values/strings.xml",
748				},
749				"bar": {
750					"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
751					"device/vendor/blah/overlay/bar/res/values/strings.xml",
752				},
753				"lib": {
754					"out/soong/.intermediates/lib2/android_common/package-res.apk",
755					"lib/res/res/values/strings.xml",
756					"device/vendor/blah/overlay/lib/res/values/strings.xml",
757				},
758			},
759			rroDirs: map[string][]string{
760				"foo": nil,
761				"bar": nil,
762			},
763		},
764		{
765			name:                       "enforce RRO on foo",
766			enforceRROTargets:          []string{"foo"},
767			enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
768			resourceFiles: map[string][]string{
769				"foo":  nil,
770				"bar":  {"bar/res/res/values/strings.xml"},
771				"lib":  nil,
772				"lib2": {"lib2/res/res/values/strings.xml"},
773			},
774			overlayFiles: map[string][]string{
775				"foo": {
776					"out/soong/.intermediates/lib2/android_common/package-res.apk",
777					"out/soong/.intermediates/lib/android_common/package-res.apk",
778					"out/soong/.intermediates/lib3/android_common/package-res.apk",
779					"foo/res/res/values/strings.xml",
780					"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
781				},
782				"bar": {
783					"device/vendor/blah/static_overlay/bar/res/values/strings.xml",
784					"device/vendor/blah/overlay/bar/res/values/strings.xml",
785				},
786				"lib": {
787					"out/soong/.intermediates/lib2/android_common/package-res.apk",
788					"lib/res/res/values/strings.xml",
789				},
790			},
791
792			rroDirs: map[string][]string{
793				"foo": {
794					"device:device/vendor/blah/overlay/foo/res",
795					"product:product/vendor/blah/overlay/foo/res",
796					"device:device/vendor/blah/overlay/lib/res",
797				},
798				"bar": nil,
799				"lib": {"device:device/vendor/blah/overlay/lib/res"},
800			},
801		},
802		{
803			name:              "enforce RRO on all",
804			enforceRROTargets: []string{"*"},
805			enforceRROExcludedOverlays: []string{
806				// Excluding specific apps/res directories also allowed.
807				"device/vendor/blah/static_overlay/foo",
808				"device/vendor/blah/static_overlay/bar/res",
809			},
810			resourceFiles: map[string][]string{
811				"foo":  nil,
812				"bar":  {"bar/res/res/values/strings.xml"},
813				"lib":  nil,
814				"lib2": {"lib2/res/res/values/strings.xml"},
815			},
816			overlayFiles: map[string][]string{
817				"foo": {
818					"out/soong/.intermediates/lib2/android_common/package-res.apk",
819					"out/soong/.intermediates/lib/android_common/package-res.apk",
820					"out/soong/.intermediates/lib3/android_common/package-res.apk",
821					"foo/res/res/values/strings.xml",
822					"device/vendor/blah/static_overlay/foo/res/values/strings.xml",
823				},
824				"bar": {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
825				"lib": {
826					"out/soong/.intermediates/lib2/android_common/package-res.apk",
827					"lib/res/res/values/strings.xml",
828				},
829			},
830			rroDirs: map[string][]string{
831				"foo": {
832					"device:device/vendor/blah/overlay/foo/res",
833					"product:product/vendor/blah/overlay/foo/res",
834					// Lib dep comes after the direct deps
835					"device:device/vendor/blah/overlay/lib/res",
836				},
837				"bar": {"device:device/vendor/blah/overlay/bar/res"},
838				"lib": {"device:device/vendor/blah/overlay/lib/res"},
839			},
840		},
841	}
842
843	deviceResourceOverlays := []string{
844		"device/vendor/blah/overlay",
845		"device/vendor/blah/overlay2",
846		"device/vendor/blah/static_overlay",
847	}
848
849	productResourceOverlays := []string{
850		"product/vendor/blah/overlay",
851	}
852
853	fs := android.MockFS{
854		"foo/res/res/values/strings.xml":                               nil,
855		"bar/res/res/values/strings.xml":                               nil,
856		"lib/res/res/values/strings.xml":                               nil,
857		"lib2/res/res/values/strings.xml":                              nil,
858		"device/vendor/blah/overlay/foo/res/values/strings.xml":        nil,
859		"device/vendor/blah/overlay/bar/res/values/strings.xml":        nil,
860		"device/vendor/blah/overlay/lib/res/values/strings.xml":        nil,
861		"device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
862		"device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
863		"device/vendor/blah/overlay2/res/values/strings.xml":           nil,
864		"product/vendor/blah/overlay/foo/res/values/strings.xml":       nil,
865	}
866
867	bp := `
868			android_app {
869				name: "foo",
870				sdk_version: "current",
871				resource_dirs: ["foo/res"],
872				static_libs: ["lib", "lib3"],
873			}
874
875			android_app {
876				name: "bar",
877				sdk_version: "current",
878				resource_dirs: ["bar/res"],
879			}
880
881			android_library {
882				name: "lib",
883				sdk_version: "current",
884				resource_dirs: ["lib/res"],
885				static_libs: ["lib2"],
886			}
887
888			android_library {
889				name: "lib2",
890				sdk_version: "current",
891				resource_dirs: ["lib2/res"],
892			}
893
894			// This library has the same resources as lib (should not lead to dupe RROs)
895			android_library {
896				name: "lib3",
897				sdk_version: "current",
898				resource_dirs: ["lib/res"]
899			}
900		`
901
902	for _, testCase := range testCases {
903		t.Run(testCase.name, func(t *testing.T) {
904			result := android.GroupFixturePreparers(
905				PrepareForTestWithJavaDefaultModules,
906				PrepareForTestWithOverlayBuildComponents,
907				fs.AddToFixture(),
908				android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
909					variables.DeviceResourceOverlays = deviceResourceOverlays
910					variables.ProductResourceOverlays = productResourceOverlays
911					if testCase.enforceRROTargets != nil {
912						variables.EnforceRROTargets = testCase.enforceRROTargets
913					}
914					if testCase.enforceRROExcludedOverlays != nil {
915						variables.EnforceRROExcludedOverlays = testCase.enforceRROExcludedOverlays
916					}
917				}),
918			).RunTestWithBp(t, bp)
919
920			resourceListToFiles := func(module android.TestingModule, list []string) (files []string) {
921				for _, o := range list {
922					res := module.MaybeOutput(o)
923					if res.Rule != nil {
924						// If the overlay is compiled as part of this module (i.e. a .arsc.flat file),
925						// verify the inputs to the .arsc.flat rule.
926						files = append(files, res.Inputs.Strings()...)
927					} else {
928						// Otherwise, verify the full path to the output of the other module
929						files = append(files, o)
930					}
931				}
932				return files
933			}
934
935			getResources := func(moduleName string) (resourceFiles, overlayFiles, rroDirs []string) {
936				module := result.ModuleForTests(moduleName, "android_common")
937				resourceList := module.MaybeOutput("aapt2/res.list")
938				if resourceList.Rule != nil {
939					resourceFiles = resourceListToFiles(module, android.PathsRelativeToTop(resourceList.Inputs))
940				}
941				overlayList := module.MaybeOutput("aapt2/overlay.list")
942				if overlayList.Rule != nil {
943					overlayFiles = resourceListToFiles(module, android.PathsRelativeToTop(overlayList.Inputs))
944				}
945
946				for _, d := range module.Module().(AndroidLibraryDependency).ExportedRRODirs() {
947					var prefix string
948					if d.overlayType == device {
949						prefix = "device:"
950					} else if d.overlayType == product {
951						prefix = "product:"
952					} else {
953						t.Fatalf("Unexpected overlayType %d", d.overlayType)
954					}
955					rroDirs = append(rroDirs, prefix+android.PathRelativeToTop(d.path))
956				}
957
958				return resourceFiles, overlayFiles, rroDirs
959			}
960
961			modules := []string{"foo", "bar", "lib", "lib2"}
962			for _, module := range modules {
963				resourceFiles, overlayFiles, rroDirs := getResources(module)
964
965				if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[module]) {
966					t.Errorf("expected %s resource files:\n  %#v\n got:\n  %#v",
967						module, testCase.resourceFiles[module], resourceFiles)
968				}
969				if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[module]) {
970					t.Errorf("expected %s overlay files:\n  %#v\n got:\n  %#v",
971						module, testCase.overlayFiles[module], overlayFiles)
972				}
973				if !reflect.DeepEqual(rroDirs, testCase.rroDirs[module]) {
974					t.Errorf("expected %s rroDirs:  %#v\n got:\n  %#v",
975						module, testCase.rroDirs[module], rroDirs)
976				}
977			}
978		})
979	}
980}
981
982func checkSdkVersion(t *testing.T, result *android.TestResult, expectedSdkVersion string) {
983	foo := result.ModuleForTests("foo", "android_common")
984	link := foo.Output("package-res.apk")
985	linkFlags := strings.Split(link.Args["flags"], " ")
986	min := android.IndexList("--min-sdk-version", linkFlags)
987	target := android.IndexList("--target-sdk-version", linkFlags)
988
989	if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
990		t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
991	}
992
993	gotMinSdkVersion := linkFlags[min+1]
994	gotTargetSdkVersion := linkFlags[target+1]
995
996	android.AssertStringEquals(t, "incorrect --min-sdk-version", expectedSdkVersion, gotMinSdkVersion)
997
998	android.AssertStringEquals(t, "incorrect --target-sdk-version", expectedSdkVersion, gotTargetSdkVersion)
999}
1000
1001func TestAppSdkVersion(t *testing.T) {
1002	testCases := []struct {
1003		name                  string
1004		sdkVersion            string
1005		platformSdkInt        int
1006		platformSdkCodename   string
1007		platformSdkFinal      bool
1008		minSdkVersionBp       string
1009		expectedMinSdkVersion string
1010		platformApis          bool
1011		activeCodenames       []string
1012	}{
1013		{
1014			name:                  "current final SDK",
1015			sdkVersion:            "current",
1016			platformSdkInt:        27,
1017			platformSdkCodename:   "REL",
1018			platformSdkFinal:      true,
1019			expectedMinSdkVersion: "27",
1020		},
1021		{
1022			name:                  "current non-final SDK",
1023			sdkVersion:            "current",
1024			platformSdkInt:        27,
1025			platformSdkCodename:   "OMR1",
1026			platformSdkFinal:      false,
1027			expectedMinSdkVersion: "OMR1",
1028			activeCodenames:       []string{"OMR1"},
1029		},
1030		{
1031			name:                  "default final SDK",
1032			sdkVersion:            "",
1033			platformApis:          true,
1034			platformSdkInt:        27,
1035			platformSdkCodename:   "REL",
1036			platformSdkFinal:      true,
1037			expectedMinSdkVersion: "27",
1038		},
1039		{
1040			name:                  "default non-final SDK",
1041			sdkVersion:            "",
1042			platformApis:          true,
1043			platformSdkInt:        27,
1044			platformSdkCodename:   "OMR1",
1045			platformSdkFinal:      false,
1046			expectedMinSdkVersion: "OMR1",
1047			activeCodenames:       []string{"OMR1"},
1048		},
1049		{
1050			name:                  "14",
1051			sdkVersion:            "14",
1052			expectedMinSdkVersion: "14",
1053			platformSdkCodename:   "S",
1054			activeCodenames:       []string{"S"},
1055		},
1056		{
1057			name:                  "two active SDKs",
1058			sdkVersion:            "module_current",
1059			minSdkVersionBp:       "UpsideDownCake",
1060			expectedMinSdkVersion: "UpsideDownCake", // And not VanillaIceCream
1061			platformSdkCodename:   "VanillaIceCream",
1062			activeCodenames:       []string{"UpsideDownCake", "VanillaIceCream"},
1063		},
1064	}
1065
1066	for _, moduleType := range []string{"android_app", "android_library"} {
1067		for _, test := range testCases {
1068			t.Run(moduleType+" "+test.name, func(t *testing.T) {
1069				platformApiProp := ""
1070				if test.platformApis {
1071					platformApiProp = "platform_apis: true,"
1072				}
1073				minSdkVersionProp := ""
1074				if test.minSdkVersionBp != "" {
1075					minSdkVersionProp = fmt.Sprintf(` min_sdk_version: "%s",`, test.minSdkVersionBp)
1076				}
1077				bp := fmt.Sprintf(`%s {
1078					name: "foo",
1079					srcs: ["a.java"],
1080					sdk_version: "%s",
1081					%s
1082					%s
1083				}`, moduleType, test.sdkVersion, platformApiProp, minSdkVersionProp)
1084
1085				result := android.GroupFixturePreparers(
1086					prepareForJavaTest,
1087					android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1088						variables.Platform_sdk_version = &test.platformSdkInt
1089						variables.Platform_sdk_codename = &test.platformSdkCodename
1090						variables.Platform_version_active_codenames = test.activeCodenames
1091						variables.Platform_sdk_final = &test.platformSdkFinal
1092					}),
1093					FixtureWithPrebuiltApis(map[string][]string{
1094						"14": {"foo"},
1095					}),
1096				).RunTestWithBp(t, bp)
1097
1098				checkSdkVersion(t, result, test.expectedMinSdkVersion)
1099			})
1100		}
1101	}
1102}
1103
1104func TestVendorAppSdkVersion(t *testing.T) {
1105	testCases := []struct {
1106		name                                  string
1107		sdkVersion                            string
1108		platformSdkInt                        int
1109		platformSdkCodename                   string
1110		platformSdkFinal                      bool
1111		deviceCurrentApiLevelForVendorModules string
1112		expectedMinSdkVersion                 string
1113	}{
1114		{
1115			name:                                  "current final SDK",
1116			sdkVersion:                            "current",
1117			platformSdkInt:                        29,
1118			platformSdkCodename:                   "REL",
1119			platformSdkFinal:                      true,
1120			deviceCurrentApiLevelForVendorModules: "29",
1121			expectedMinSdkVersion:                 "29",
1122		},
1123		{
1124			name:                                  "current final SDK",
1125			sdkVersion:                            "current",
1126			platformSdkInt:                        29,
1127			platformSdkCodename:                   "REL",
1128			platformSdkFinal:                      true,
1129			deviceCurrentApiLevelForVendorModules: "28",
1130			expectedMinSdkVersion:                 "28",
1131		},
1132		{
1133			name:                                  "current final SDK",
1134			sdkVersion:                            "current",
1135			platformSdkInt:                        29,
1136			platformSdkCodename:                   "Q",
1137			platformSdkFinal:                      false,
1138			deviceCurrentApiLevelForVendorModules: "28",
1139			expectedMinSdkVersion:                 "28",
1140		},
1141	}
1142
1143	for _, moduleType := range []string{"android_app", "android_library"} {
1144		for _, sdkKind := range []string{"", "system_"} {
1145			for _, test := range testCases {
1146				t.Run(moduleType+" "+test.name, func(t *testing.T) {
1147					bp := fmt.Sprintf(`%s {
1148						name: "foo",
1149						srcs: ["a.java"],
1150						sdk_version: "%s%s",
1151						vendor: true,
1152					}`, moduleType, sdkKind, test.sdkVersion)
1153
1154					result := android.GroupFixturePreparers(
1155						prepareForJavaTest,
1156						android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1157							variables.Platform_sdk_version = &test.platformSdkInt
1158							variables.Platform_sdk_codename = &test.platformSdkCodename
1159							variables.Platform_sdk_final = &test.platformSdkFinal
1160							variables.DeviceCurrentApiLevelForVendorModules = &test.deviceCurrentApiLevelForVendorModules
1161							variables.DeviceSystemSdkVersions = []string{"28", "29"}
1162						}),
1163						FixtureWithPrebuiltApis(map[string][]string{
1164							"28":      {"foo"},
1165							"29":      {"foo"},
1166							"current": {"foo"},
1167						}),
1168					).RunTestWithBp(t, bp)
1169
1170					checkSdkVersion(t, result, test.expectedMinSdkVersion)
1171				})
1172			}
1173		}
1174	}
1175}
1176
1177func TestJNIABI(t *testing.T) {
1178	ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
1179		cc_library {
1180			name: "libjni",
1181			system_shared_libs: [],
1182			sdk_version: "current",
1183			stl: "none",
1184		}
1185
1186		android_test {
1187			name: "test",
1188			sdk_version: "core_platform",
1189			jni_libs: ["libjni"],
1190		}
1191
1192		android_test {
1193			name: "test_first",
1194			sdk_version: "core_platform",
1195			compile_multilib: "first",
1196			jni_libs: ["libjni"],
1197		}
1198
1199		android_test {
1200			name: "test_both",
1201			sdk_version: "core_platform",
1202			compile_multilib: "both",
1203			jni_libs: ["libjni"],
1204		}
1205
1206		android_test {
1207			name: "test_32",
1208			sdk_version: "core_platform",
1209			compile_multilib: "32",
1210			jni_libs: ["libjni"],
1211		}
1212
1213		android_test {
1214			name: "test_64",
1215			sdk_version: "core_platform",
1216			compile_multilib: "64",
1217			jni_libs: ["libjni"],
1218		}
1219		`)
1220
1221	testCases := []struct {
1222		name string
1223		abis []string
1224	}{
1225		{"test", []string{"arm64-v8a"}},
1226		{"test_first", []string{"arm64-v8a"}},
1227		{"test_both", []string{"arm64-v8a", "armeabi-v7a"}},
1228		{"test_32", []string{"armeabi-v7a"}},
1229		{"test_64", []string{"arm64-v8a"}},
1230	}
1231
1232	for _, test := range testCases {
1233		t.Run(test.name, func(t *testing.T) {
1234			app := ctx.ModuleForTests(test.name, "android_common")
1235			jniLibZip := app.Output(jniJarOutputPathString)
1236			var abis []string
1237			args := strings.Fields(jniLibZip.Args["jarArgs"])
1238			for i := 0; i < len(args); i++ {
1239				if args[i] == "-P" {
1240					abis = append(abis, filepath.Base(args[i+1]))
1241					i++
1242				}
1243			}
1244			if !reflect.DeepEqual(abis, test.abis) {
1245				t.Errorf("want abis %v, got %v", test.abis, abis)
1246			}
1247		})
1248	}
1249}
1250
1251func TestAppSdkVersionByPartition(t *testing.T) {
1252	testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
1253		android_app {
1254			name: "foo",
1255			srcs: ["a.java"],
1256			vendor: true,
1257			platform_apis: true,
1258		}
1259	`)
1260
1261	testJava(t, `
1262		android_app {
1263			name: "bar",
1264			srcs: ["b.java"],
1265			platform_apis: true,
1266		}
1267	`)
1268
1269	for _, enforce := range []bool{true, false} {
1270		bp := `
1271			android_app {
1272				name: "foo",
1273				srcs: ["a.java"],
1274				product_specific: true,
1275				platform_apis: true,
1276			}
1277		`
1278
1279		errorHandler := android.FixtureExpectsNoErrors
1280		if enforce {
1281			errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern("sdk_version must have a value when the module is located at vendor or product")
1282		}
1283
1284		android.GroupFixturePreparers(
1285			PrepareForTestWithJavaDefaultModules,
1286			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1287				variables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce)
1288			}),
1289		).
1290			ExtendWithErrorHandler(errorHandler).
1291			RunTestWithBp(t, bp)
1292	}
1293}
1294
1295func TestJNIPackaging(t *testing.T) {
1296	ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
1297		cc_library {
1298			name: "libjni",
1299			system_shared_libs: [],
1300			stl: "none",
1301			sdk_version: "current",
1302		}
1303
1304		android_app {
1305			name: "app",
1306			jni_libs: ["libjni"],
1307			sdk_version: "current",
1308		}
1309
1310		android_app {
1311			name: "app_noembed",
1312			jni_libs: ["libjni"],
1313			use_embedded_native_libs: false,
1314			sdk_version: "current",
1315		}
1316
1317		android_app {
1318			name: "app_embed",
1319			jni_libs: ["libjni"],
1320			use_embedded_native_libs: true,
1321			sdk_version: "current",
1322		}
1323
1324		android_test {
1325			name: "test",
1326			sdk_version: "current",
1327			jni_libs: ["libjni"],
1328		}
1329
1330		android_test {
1331			name: "test_noembed",
1332			sdk_version: "current",
1333			jni_libs: ["libjni"],
1334			use_embedded_native_libs: false,
1335		}
1336
1337		android_test_helper_app {
1338			name: "test_helper",
1339			sdk_version: "current",
1340			jni_libs: ["libjni"],
1341		}
1342
1343		android_test_helper_app {
1344			name: "test_helper_noembed",
1345			sdk_version: "current",
1346			jni_libs: ["libjni"],
1347			use_embedded_native_libs: false,
1348		}
1349		`)
1350
1351	testCases := []struct {
1352		name       string
1353		packaged   bool
1354		compressed bool
1355	}{
1356		{"app", false, false},
1357		{"app_noembed", false, false},
1358		{"app_embed", true, false},
1359		{"test", true, false},
1360		{"test_noembed", true, true},
1361		{"test_helper", true, false},
1362		{"test_helper_noembed", true, true},
1363	}
1364
1365	for _, test := range testCases {
1366		t.Run(test.name, func(t *testing.T) {
1367			app := ctx.ModuleForTests(test.name, "android_common")
1368			jniLibZip := app.MaybeOutput(jniJarOutputPathString)
1369			if g, w := (jniLibZip.Rule != nil), test.packaged; g != w {
1370				t.Errorf("expected jni packaged %v, got %v", w, g)
1371			}
1372
1373			if jniLibZip.Rule != nil {
1374				if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w {
1375					t.Errorf("expected jni compressed %v, got %v", w, g)
1376				}
1377
1378				if !strings.Contains(jniLibZip.Implicits[0].String(), "_sdk_") {
1379					t.Errorf("expected input %q to use sdk variant", jniLibZip.Implicits[0].String())
1380				}
1381			}
1382		})
1383	}
1384}
1385
1386func TestJNISDK(t *testing.T) {
1387	ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
1388		cc_library {
1389			name: "libjni",
1390			system_shared_libs: [],
1391			stl: "none",
1392			sdk_version: "current",
1393		}
1394
1395		android_test {
1396			name: "app_platform",
1397			jni_libs: ["libjni"],
1398			platform_apis: true,
1399		}
1400
1401		android_test {
1402			name: "app_sdk",
1403			jni_libs: ["libjni"],
1404			sdk_version: "current",
1405		}
1406
1407		android_test {
1408			name: "app_force_platform",
1409			jni_libs: ["libjni"],
1410			sdk_version: "current",
1411			jni_uses_platform_apis: true,
1412		}
1413
1414		android_test {
1415			name: "app_force_sdk",
1416			jni_libs: ["libjni"],
1417			platform_apis: true,
1418			jni_uses_sdk_apis: true,
1419		}
1420
1421		cc_library {
1422			name: "libvendorjni",
1423			system_shared_libs: [],
1424			stl: "none",
1425			vendor: true,
1426		}
1427
1428		android_test {
1429			name: "app_vendor",
1430			jni_libs: ["libvendorjni"],
1431			sdk_version: "current",
1432			vendor: true,
1433		}
1434	`)
1435
1436	testCases := []struct {
1437		name      string
1438		sdkJNI    bool
1439		vendorJNI bool
1440	}{
1441		{name: "app_platform"},
1442		{name: "app_sdk", sdkJNI: true},
1443		{name: "app_force_platform"},
1444		{name: "app_force_sdk", sdkJNI: true},
1445		{name: "app_vendor", vendorJNI: true},
1446	}
1447
1448	platformJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_shared").
1449		Output("libjni.so").Output.String()
1450	sdkJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").
1451		Output("libjni.so").Output.String()
1452	vendorJNI := ctx.ModuleForTests("libvendorjni", "android_arm64_armv8-a_shared").
1453		Output("libvendorjni.so").Output.String()
1454
1455	for _, test := range testCases {
1456		t.Run(test.name, func(t *testing.T) {
1457			app := ctx.ModuleForTests(test.name, "android_common")
1458
1459			jniLibZip := app.MaybeOutput(jniJarOutputPathString)
1460			if len(jniLibZip.Implicits) != 1 {
1461				t.Fatalf("expected exactly one jni library, got %q", jniLibZip.Implicits.Strings())
1462			}
1463			gotJNI := jniLibZip.Implicits[0].String()
1464
1465			if test.sdkJNI {
1466				if gotJNI != sdkJNI {
1467					t.Errorf("expected SDK JNI library %q, got %q", sdkJNI, gotJNI)
1468				}
1469			} else if test.vendorJNI {
1470				if gotJNI != vendorJNI {
1471					t.Errorf("expected platform JNI library %q, got %q", vendorJNI, gotJNI)
1472				}
1473			} else {
1474				if gotJNI != platformJNI {
1475					t.Errorf("expected platform JNI library %q, got %q", platformJNI, gotJNI)
1476				}
1477			}
1478		})
1479	}
1480
1481	t.Run("jni_uses_platform_apis_error", func(t *testing.T) {
1482		testJavaError(t, `jni_uses_platform_apis: can only be set for modules that set sdk_version`, `
1483			android_test {
1484				name: "app_platform",
1485				platform_apis: true,
1486				jni_uses_platform_apis: true,
1487			}
1488		`)
1489	})
1490
1491	t.Run("jni_uses_sdk_apis_error", func(t *testing.T) {
1492		testJavaError(t, `jni_uses_sdk_apis: can only be set for modules that do not set sdk_version`, `
1493			android_test {
1494				name: "app_sdk",
1495				sdk_version: "current",
1496				jni_uses_sdk_apis: true,
1497			}
1498		`)
1499	})
1500
1501}
1502
1503func TestCertificates(t *testing.T) {
1504	testCases := []struct {
1505		name                     string
1506		bp                       string
1507		allowMissingDependencies bool
1508		certificateOverride      string
1509		expectedCertSigningFlags string
1510		expectedCertificate      string
1511	}{
1512		{
1513			name: "default",
1514			bp: `
1515				android_app {
1516					name: "foo",
1517					srcs: ["a.java"],
1518					sdk_version: "current",
1519				}
1520			`,
1521			certificateOverride:      "",
1522			expectedCertSigningFlags: "",
1523			expectedCertificate:      "build/make/target/product/security/testkey",
1524		},
1525		{
1526			name: "module certificate property",
1527			bp: `
1528				android_app {
1529					name: "foo",
1530					srcs: ["a.java"],
1531					certificate: ":new_certificate",
1532					sdk_version: "current",
1533				}
1534
1535				android_app_certificate {
1536					name: "new_certificate",
1537					certificate: "cert/new_cert",
1538				}
1539			`,
1540			certificateOverride:      "",
1541			expectedCertSigningFlags: "",
1542			expectedCertificate:      "cert/new_cert",
1543		},
1544		{
1545			name: "path certificate property",
1546			bp: `
1547				android_app {
1548					name: "foo",
1549					srcs: ["a.java"],
1550					certificate: "expiredkey",
1551					sdk_version: "current",
1552				}
1553			`,
1554			certificateOverride:      "",
1555			expectedCertSigningFlags: "",
1556			expectedCertificate:      "build/make/target/product/security/expiredkey",
1557		},
1558		{
1559			name: "certificate overrides",
1560			bp: `
1561				android_app {
1562					name: "foo",
1563					srcs: ["a.java"],
1564					certificate: "expiredkey",
1565					sdk_version: "current",
1566				}
1567
1568				android_app_certificate {
1569					name: "new_certificate",
1570					certificate: "cert/new_cert",
1571				}
1572			`,
1573			certificateOverride:      "foo:new_certificate",
1574			expectedCertSigningFlags: "",
1575			expectedCertificate:      "cert/new_cert",
1576		},
1577		{
1578			name: "certificate signing flags",
1579			bp: `
1580				android_app {
1581					name: "foo",
1582					srcs: ["a.java"],
1583					certificate: ":new_certificate",
1584					lineage: "lineage.bin",
1585					rotationMinSdkVersion: "32",
1586					sdk_version: "current",
1587				}
1588
1589				android_app_certificate {
1590					name: "new_certificate",
1591					certificate: "cert/new_cert",
1592				}
1593			`,
1594			certificateOverride:      "",
1595			expectedCertSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32",
1596			expectedCertificate:      "cert/new_cert",
1597		},
1598		{
1599			name: "cert signing flags from filegroup",
1600			bp: `
1601				android_app {
1602					name: "foo",
1603					srcs: ["a.java"],
1604					certificate: ":new_certificate",
1605					lineage: ":lineage_bin",
1606					rotationMinSdkVersion: "32",
1607					sdk_version: "current",
1608				}
1609
1610				android_app_certificate {
1611					name: "new_certificate",
1612					certificate: "cert/new_cert",
1613				}
1614
1615				filegroup {
1616					name: "lineage_bin",
1617					srcs: ["lineage.bin"],
1618				}
1619			`,
1620			certificateOverride:      "",
1621			expectedCertSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32",
1622			expectedCertificate:      "cert/new_cert",
1623		},
1624		{
1625			name: "missing with AllowMissingDependencies",
1626			bp: `
1627				android_app {
1628					name: "foo",
1629					srcs: ["a.java"],
1630					certificate: ":new_certificate",
1631					sdk_version: "current",
1632				}
1633			`,
1634			expectedCertificate:      "out/soong/.intermediates/foo/android_common/missing",
1635			allowMissingDependencies: true,
1636		},
1637	}
1638
1639	for _, test := range testCases {
1640		t.Run(test.name, func(t *testing.T) {
1641			result := android.GroupFixturePreparers(
1642				PrepareForTestWithJavaDefaultModules,
1643				android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1644					if test.certificateOverride != "" {
1645						variables.CertificateOverrides = []string{test.certificateOverride}
1646					}
1647					if test.allowMissingDependencies {
1648						variables.Allow_missing_dependencies = proptools.BoolPtr(true)
1649					}
1650				}),
1651				android.FixtureModifyContext(func(ctx *android.TestContext) {
1652					ctx.SetAllowMissingDependencies(test.allowMissingDependencies)
1653				}),
1654			).RunTestWithBp(t, test.bp)
1655
1656			foo := result.ModuleForTests("foo", "android_common")
1657
1658			certificate := foo.Module().(*AndroidApp).certificate
1659			android.AssertPathRelativeToTopEquals(t, "certificates key", test.expectedCertificate+".pk8", certificate.Key)
1660			// The sign_target_files_apks and check_target_files_signatures
1661			// tools require that certificates have a .x509.pem extension.
1662			android.AssertPathRelativeToTopEquals(t, "certificates pem", test.expectedCertificate+".x509.pem", certificate.Pem)
1663
1664			signapk := foo.Output("foo.apk")
1665			if signapk.Rule != android.ErrorRule {
1666				signCertificateFlags := signapk.Args["certificates"]
1667				expectedFlags := certificate.Pem.String() + " " + certificate.Key.String()
1668				android.AssertStringEquals(t, "certificates flags", expectedFlags, signCertificateFlags)
1669
1670				certSigningFlags := signapk.Args["flags"]
1671				android.AssertStringEquals(t, "cert signing flags", test.expectedCertSigningFlags, certSigningFlags)
1672			}
1673		})
1674	}
1675}
1676
1677func TestRequestV4SigningFlag(t *testing.T) {
1678	testCases := []struct {
1679		name     string
1680		bp       string
1681		expected string
1682	}{
1683		{
1684			name: "default",
1685			bp: `
1686				android_app {
1687					name: "foo",
1688					srcs: ["a.java"],
1689					sdk_version: "current",
1690				}
1691			`,
1692			expected: "",
1693		},
1694		{
1695			name: "default",
1696			bp: `
1697				android_app {
1698					name: "foo",
1699					srcs: ["a.java"],
1700					sdk_version: "current",
1701					v4_signature: false,
1702				}
1703			`,
1704			expected: "",
1705		},
1706		{
1707			name: "module certificate property",
1708			bp: `
1709				android_app {
1710					name: "foo",
1711					srcs: ["a.java"],
1712					sdk_version: "current",
1713					v4_signature: true,
1714				}
1715			`,
1716			expected: "--enable-v4",
1717		},
1718	}
1719
1720	for _, test := range testCases {
1721		t.Run(test.name, func(t *testing.T) {
1722			result := android.GroupFixturePreparers(
1723				PrepareForTestWithJavaDefaultModules,
1724			).RunTestWithBp(t, test.bp)
1725
1726			foo := result.ModuleForTests("foo", "android_common")
1727
1728			signapk := foo.Output("foo.apk")
1729			signFlags := signapk.Args["flags"]
1730			android.AssertStringEquals(t, "signing flags", test.expected, signFlags)
1731		})
1732	}
1733}
1734
1735func TestPackageNameOverride(t *testing.T) {
1736	testCases := []struct {
1737		name                string
1738		bp                  string
1739		packageNameOverride string
1740		expected            []string
1741	}{
1742		{
1743			name: "default",
1744			bp: `
1745				android_app {
1746					name: "foo",
1747					srcs: ["a.java"],
1748					sdk_version: "current",
1749				}
1750			`,
1751			packageNameOverride: "",
1752			expected: []string{
1753				"out/soong/.intermediates/foo/android_common/foo.apk",
1754				"out/soong/target/product/test_device/system/app/foo/foo.apk",
1755			},
1756		},
1757		{
1758			name: "overridden via PRODUCT_PACKAGE_NAME_OVERRIDES",
1759			bp: `
1760				android_app {
1761					name: "foo",
1762					srcs: ["a.java"],
1763					sdk_version: "current",
1764				}
1765			`,
1766			packageNameOverride: "foo:bar",
1767			expected: []string{
1768				// The package apk should be still be the original name for test dependencies.
1769				"out/soong/.intermediates/foo/android_common/bar.apk",
1770				"out/soong/target/product/test_device/system/app/bar/bar.apk",
1771			},
1772		},
1773		{
1774			name: "overridden via stem",
1775			bp: `
1776				android_app {
1777					name: "foo",
1778					srcs: ["a.java"],
1779					sdk_version: "current",
1780					stem: "bar",
1781				}
1782			`,
1783			packageNameOverride: "",
1784			expected: []string{
1785				"out/soong/.intermediates/foo/android_common/bar.apk",
1786				"out/soong/target/product/test_device/system/app/bar/bar.apk",
1787			},
1788		},
1789	}
1790
1791	for _, test := range testCases {
1792		t.Run(test.name, func(t *testing.T) {
1793			result := android.GroupFixturePreparers(
1794				PrepareForTestWithJavaDefaultModules,
1795				android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1796					if test.packageNameOverride != "" {
1797						variables.PackageNameOverrides = []string{test.packageNameOverride}
1798					}
1799				}),
1800			).RunTestWithBp(t, test.bp)
1801
1802			foo := result.ModuleForTests("foo", "android_common")
1803
1804			outSoongDir := result.Config.SoongOutDir()
1805
1806			outputs := foo.AllOutputs()
1807			outputMap := make(map[string]bool)
1808			for _, o := range outputs {
1809				outputMap[android.StringPathRelativeToTop(outSoongDir, o)] = true
1810			}
1811			for _, e := range test.expected {
1812				if _, exist := outputMap[e]; !exist {
1813					t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
1814				}
1815			}
1816		})
1817	}
1818}
1819
1820func TestInstrumentationTargetOverridden(t *testing.T) {
1821	bp := `
1822		android_app {
1823			name: "foo",
1824			srcs: ["a.java"],
1825			sdk_version: "current",
1826		}
1827
1828		android_test {
1829			name: "bar",
1830			instrumentation_for: "foo",
1831			sdk_version: "current",
1832		}
1833		`
1834
1835	result := android.GroupFixturePreparers(
1836		PrepareForTestWithJavaDefaultModules,
1837		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1838			variables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"}
1839		}),
1840	).RunTestWithBp(t, bp)
1841
1842	bar := result.ModuleForTests("bar", "android_common")
1843	res := bar.Output("package-res.apk")
1844	aapt2Flags := res.Args["flags"]
1845	e := "--rename-instrumentation-target-package org.dandroid.bp"
1846	if !strings.Contains(aapt2Flags, e) {
1847		t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
1848	}
1849}
1850
1851func TestOverrideAndroidApp(t *testing.T) {
1852	result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
1853		t, `
1854		android_app {
1855			name: "foo",
1856			srcs: ["a.java"],
1857			certificate: "expiredkey",
1858			overrides: ["qux"],
1859			sdk_version: "current",
1860		}
1861
1862		override_android_app {
1863			name: "bar",
1864			base: "foo",
1865			certificate: ":new_certificate",
1866			lineage: "lineage.bin",
1867			rotationMinSdkVersion: "32",
1868			logging_parent: "bah",
1869		}
1870
1871		android_app_certificate {
1872			name: "new_certificate",
1873			certificate: "cert/new_cert",
1874		}
1875
1876		override_android_app {
1877			name: "baz",
1878			base: "foo",
1879			package_name: "org.dandroid.bp",
1880		}
1881
1882		override_android_app {
1883			name: "baz_no_rename_resources",
1884			base: "foo",
1885			package_name: "org.dandroid.bp",
1886			rename_resources_package: false,
1887		}
1888
1889		android_app {
1890			name: "foo_no_rename_resources",
1891			srcs: ["a.java"],
1892			certificate: "expiredkey",
1893			overrides: ["qux"],
1894			rename_resources_package: false,
1895			sdk_version: "current",
1896		}
1897
1898		override_android_app {
1899			name: "baz_base_no_rename_resources",
1900			base: "foo_no_rename_resources",
1901			package_name: "org.dandroid.bp",
1902		}
1903
1904		override_android_app {
1905			name: "baz_override_base_rename_resources",
1906			base: "foo_no_rename_resources",
1907			package_name: "org.dandroid.bp",
1908			rename_resources_package: true,
1909		}
1910		`)
1911
1912	expectedVariants := []struct {
1913		name             string
1914		moduleName       string
1915		variantName      string
1916		apkName          string
1917		apkPath          string
1918		certFlag         string
1919		certSigningFlags string
1920		overrides        []string
1921		packageFlag      string
1922		renameResources  bool
1923		logging_parent   string
1924	}{
1925		{
1926			name:             "foo",
1927			moduleName:       "foo",
1928			variantName:      "android_common",
1929			apkPath:          "out/soong/target/product/test_device/system/app/foo/foo.apk",
1930			certFlag:         "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1931			certSigningFlags: "",
1932			overrides:        []string{"qux"},
1933			packageFlag:      "",
1934			renameResources:  false,
1935			logging_parent:   "",
1936		},
1937		{
1938			name:             "foo",
1939			moduleName:       "bar",
1940			variantName:      "android_common_bar",
1941			apkPath:          "out/soong/target/product/test_device/system/app/bar/bar.apk",
1942			certFlag:         "cert/new_cert.x509.pem cert/new_cert.pk8",
1943			certSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32",
1944			overrides:        []string{"qux", "foo"},
1945			packageFlag:      "",
1946			renameResources:  false,
1947			logging_parent:   "bah",
1948		},
1949		{
1950			name:             "foo",
1951			moduleName:       "baz",
1952			variantName:      "android_common_baz",
1953			apkPath:          "out/soong/target/product/test_device/system/app/baz/baz.apk",
1954			certFlag:         "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1955			certSigningFlags: "",
1956			overrides:        []string{"qux", "foo"},
1957			packageFlag:      "org.dandroid.bp",
1958			renameResources:  true,
1959			logging_parent:   "",
1960		},
1961		{
1962			name:             "foo",
1963			moduleName:       "baz_no_rename_resources",
1964			variantName:      "android_common_baz_no_rename_resources",
1965			apkPath:          "out/soong/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk",
1966			certFlag:         "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1967			certSigningFlags: "",
1968			overrides:        []string{"qux", "foo"},
1969			packageFlag:      "org.dandroid.bp",
1970			renameResources:  false,
1971			logging_parent:   "",
1972		},
1973		{
1974			name:             "foo_no_rename_resources",
1975			moduleName:       "baz_base_no_rename_resources",
1976			variantName:      "android_common_baz_base_no_rename_resources",
1977			apkPath:          "out/soong/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk",
1978			certFlag:         "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1979			certSigningFlags: "",
1980			overrides:        []string{"qux", "foo_no_rename_resources"},
1981			packageFlag:      "org.dandroid.bp",
1982			renameResources:  false,
1983			logging_parent:   "",
1984		},
1985		{
1986			name:             "foo_no_rename_resources",
1987			moduleName:       "baz_override_base_rename_resources",
1988			variantName:      "android_common_baz_override_base_rename_resources",
1989			apkPath:          "out/soong/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk",
1990			certFlag:         "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
1991			certSigningFlags: "",
1992			overrides:        []string{"qux", "foo_no_rename_resources"},
1993			packageFlag:      "org.dandroid.bp",
1994			renameResources:  true,
1995			logging_parent:   "",
1996		},
1997	}
1998	for _, expected := range expectedVariants {
1999		variant := result.ModuleForTests(expected.name, expected.variantName)
2000
2001		// Check the final apk name
2002		variant.Output(expected.apkPath)
2003
2004		// Check the certificate paths
2005		signapk := variant.Output(expected.moduleName + ".apk")
2006		certFlag := signapk.Args["certificates"]
2007		android.AssertStringEquals(t, "certificates flags", expected.certFlag, certFlag)
2008
2009		// Check the cert signing flags
2010		certSigningFlags := signapk.Args["flags"]
2011		android.AssertStringEquals(t, "cert signing flags", expected.certSigningFlags, certSigningFlags)
2012
2013		// Check if the overrides field values are correctly aggregated.
2014		mod := variant.Module().(*AndroidApp)
2015		android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.overridableAppProperties.Overrides)
2016
2017		// Test Overridable property: Logging_parent
2018		logging_parent := mod.aapt.LoggingParent
2019		android.AssertStringEquals(t, "overrides property value for logging parent", expected.logging_parent, logging_parent)
2020
2021		// Check the package renaming flag, if exists.
2022		res := variant.Output("package-res.apk")
2023		aapt2Flags := res.Args["flags"]
2024		checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
2025		expectedPackage := expected.packageFlag
2026		if !expected.renameResources {
2027			expectedPackage = ""
2028		}
2029		checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expectedPackage)
2030	}
2031}
2032
2033func TestOverrideAndroidAppOverrides(t *testing.T) {
2034	ctx, _ := testJava(
2035		t, `
2036		android_app {
2037			name: "foo",
2038			srcs: ["a.java"],
2039			sdk_version: "current",
2040			overrides: ["qux"]
2041		}
2042
2043		android_app {
2044			name: "bar",
2045			srcs: ["b.java"],
2046			sdk_version: "current",
2047			overrides: ["foo"]
2048		}
2049
2050		override_android_app {
2051			name: "foo_override",
2052			base: "foo",
2053			overrides: ["bar"]
2054		}
2055		`)
2056
2057	expectedVariants := []struct {
2058		name        string
2059		moduleName  string
2060		variantName string
2061		overrides   []string
2062	}{
2063		{
2064			name:        "foo",
2065			moduleName:  "foo",
2066			variantName: "android_common",
2067			overrides:   []string{"qux"},
2068		},
2069		{
2070			name:        "bar",
2071			moduleName:  "bar",
2072			variantName: "android_common",
2073			overrides:   []string{"foo"},
2074		},
2075		{
2076			name:        "foo",
2077			moduleName:  "foo_override",
2078			variantName: "android_common_foo_override",
2079			overrides:   []string{"bar", "foo"},
2080		},
2081	}
2082	for _, expected := range expectedVariants {
2083		variant := ctx.ModuleForTests(expected.name, expected.variantName)
2084
2085		// Check if the overrides field values are correctly aggregated.
2086		mod := variant.Module().(*AndroidApp)
2087		android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.overridableAppProperties.Overrides)
2088	}
2089}
2090
2091func TestOverrideAndroidAppWithPrebuilt(t *testing.T) {
2092	result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
2093		t, `
2094		android_app {
2095			name: "foo",
2096			srcs: ["a.java"],
2097			sdk_version: "current",
2098		}
2099
2100		override_android_app {
2101			name: "bar",
2102			base: "foo",
2103		}
2104
2105		android_app_import {
2106			name: "bar",
2107			prefer: true,
2108			apk: "bar.apk",
2109			presigned: true,
2110		}
2111		`)
2112
2113	// An app that has an override that also has a prebuilt should not be hidden.
2114	foo := result.ModuleForTests("foo", "android_common")
2115	if foo.Module().IsHideFromMake() {
2116		t.Errorf("expected foo to have HideFromMake false")
2117	}
2118
2119	// An override that also has a prebuilt should be hidden.
2120	barOverride := result.ModuleForTests("foo", "android_common_bar")
2121	if !barOverride.Module().IsHideFromMake() {
2122		t.Errorf("expected bar override variant of foo to have HideFromMake true")
2123	}
2124}
2125
2126func TestOverrideAndroidAppStem(t *testing.T) {
2127	ctx, _ := testJava(t, `
2128		android_app {
2129			name: "foo",
2130			srcs: ["a.java"],
2131			sdk_version: "current",
2132		}
2133		override_android_app {
2134			name: "bar",
2135			base: "foo",
2136		}
2137		override_android_app {
2138			name: "baz",
2139			base: "foo",
2140			stem: "baz_stem",
2141		}
2142		android_app {
2143			name: "foo2",
2144			srcs: ["a.java"],
2145			sdk_version: "current",
2146			stem: "foo2_stem",
2147		}
2148		override_android_app {
2149			name: "bar2",
2150			base: "foo2",
2151		}
2152		override_android_app {
2153			name: "baz2",
2154			base: "foo2",
2155			stem: "baz2_stem",
2156		}
2157	`)
2158	for _, expected := range []struct {
2159		moduleName  string
2160		variantName string
2161		apkPath     string
2162	}{
2163		{
2164			moduleName:  "foo",
2165			variantName: "android_common",
2166			apkPath:     "out/soong/target/product/test_device/system/app/foo/foo.apk",
2167		},
2168		{
2169			moduleName:  "foo",
2170			variantName: "android_common_bar",
2171			apkPath:     "out/soong/target/product/test_device/system/app/bar/bar.apk",
2172		},
2173		{
2174			moduleName:  "foo",
2175			variantName: "android_common_baz",
2176			apkPath:     "out/soong/target/product/test_device/system/app/baz_stem/baz_stem.apk",
2177		},
2178		{
2179			moduleName:  "foo2",
2180			variantName: "android_common",
2181			apkPath:     "out/soong/target/product/test_device/system/app/foo2_stem/foo2_stem.apk",
2182		},
2183		{
2184			moduleName:  "foo2",
2185			variantName: "android_common_bar2",
2186			// Note that this may cause the duplicate output error.
2187			apkPath: "out/soong/target/product/test_device/system/app/foo2_stem/foo2_stem.apk",
2188		},
2189		{
2190			moduleName:  "foo2",
2191			variantName: "android_common_baz2",
2192			apkPath:     "out/soong/target/product/test_device/system/app/baz2_stem/baz2_stem.apk",
2193		},
2194	} {
2195		variant := ctx.ModuleForTests(expected.moduleName, expected.variantName)
2196		variant.Output(expected.apkPath)
2197	}
2198}
2199
2200func TestOverrideAndroidAppDependency(t *testing.T) {
2201	ctx, _ := testJava(t, `
2202		android_app {
2203			name: "foo",
2204			srcs: ["a.java"],
2205			sdk_version: "current",
2206		}
2207
2208		override_android_app {
2209			name: "bar",
2210			base: "foo",
2211			package_name: "org.dandroid.bp",
2212		}
2213
2214		android_test {
2215			name: "baz",
2216			srcs: ["b.java"],
2217			instrumentation_for: "foo",
2218		}
2219
2220		android_test {
2221			name: "qux",
2222			srcs: ["b.java"],
2223			instrumentation_for: "bar",
2224		}
2225		`)
2226
2227	// Verify baz, which depends on the overridden module foo, has the correct classpath javac arg.
2228	javac := ctx.ModuleForTests("baz", "android_common").Rule("javac")
2229	fooTurbine := "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar"
2230	if !strings.Contains(javac.Args["classpath"], fooTurbine) {
2231		t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine)
2232	}
2233
2234	// Verify qux, which depends on the overriding module bar, has the correct classpath javac arg.
2235	javac = ctx.ModuleForTests("qux", "android_common").Rule("javac")
2236	barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine-combined/foo.jar"
2237	if !strings.Contains(javac.Args["classpath"], barTurbine) {
2238		t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
2239	}
2240}
2241
2242func TestOverrideAndroidTest(t *testing.T) {
2243	ctx, _ := testJava(t, `
2244		android_app {
2245			name: "foo",
2246			srcs: ["a.java"],
2247			package_name: "com.android.foo",
2248			sdk_version: "current",
2249		}
2250
2251		override_android_app {
2252			name: "bar",
2253			base: "foo",
2254			package_name: "com.android.bar",
2255		}
2256
2257		android_test {
2258			name: "foo_test",
2259			srcs: ["b.java"],
2260			instrumentation_for: "foo",
2261		}
2262
2263		override_android_test {
2264			name: "bar_test",
2265			base: "foo_test",
2266			package_name: "com.android.bar.test",
2267			instrumentation_for: "bar",
2268			instrumentation_target_package: "com.android.bar",
2269		}
2270		`)
2271
2272	expectedVariants := []struct {
2273		moduleName        string
2274		variantName       string
2275		apkPath           string
2276		overrides         []string
2277		targetVariant     string
2278		packageFlag       string
2279		targetPackageFlag string
2280	}{
2281		{
2282			variantName:       "android_common",
2283			apkPath:           "/target/product/test_device/testcases/foo_test/arm64/foo_test.apk",
2284			overrides:         nil,
2285			targetVariant:     "android_common",
2286			packageFlag:       "",
2287			targetPackageFlag: "",
2288		},
2289		{
2290			variantName:       "android_common_bar_test",
2291			apkPath:           "/target/product/test_device/testcases/bar_test/arm64/bar_test.apk",
2292			overrides:         []string{"foo_test"},
2293			targetVariant:     "android_common_bar",
2294			packageFlag:       "com.android.bar.test",
2295			targetPackageFlag: "com.android.bar",
2296		},
2297	}
2298	for _, expected := range expectedVariants {
2299		variant := ctx.ModuleForTests("foo_test", expected.variantName)
2300
2301		// Check the final apk name
2302		variant.Output("out/soong" + expected.apkPath)
2303
2304		// Check if the overrides field values are correctly aggregated.
2305		mod := variant.Module().(*AndroidTest)
2306		if !reflect.DeepEqual(expected.overrides, mod.overridableAppProperties.Overrides) {
2307			t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
2308				expected.overrides, mod.overridableAppProperties.Overrides)
2309		}
2310
2311		// Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides.
2312		javac := variant.Rule("javac")
2313		turbine := filepath.Join("out", "soong", ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar")
2314		if !strings.Contains(javac.Args["classpath"], turbine) {
2315			t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine)
2316		}
2317
2318		// Check aapt2 flags.
2319		res := variant.Output("package-res.apk")
2320		aapt2Flags := res.Args["flags"]
2321		checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
2322		checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expected.packageFlag)
2323		checkAapt2LinkFlag(t, aapt2Flags, "rename-instrumentation-target-package", expected.targetPackageFlag)
2324	}
2325}
2326
2327func TestAndroidTest_FixTestConfig(t *testing.T) {
2328	ctx, _ := testJava(t, `
2329		android_app {
2330			name: "foo",
2331			srcs: ["a.java"],
2332			package_name: "com.android.foo",
2333			sdk_version: "current",
2334		}
2335
2336		android_test {
2337			name: "foo_test",
2338			srcs: ["b.java"],
2339			instrumentation_for: "foo",
2340		}
2341
2342		android_test {
2343			name: "bar_test",
2344			srcs: ["b.java"],
2345			package_name: "com.android.bar.test",
2346			instrumentation_for: "foo",
2347			mainline_package_name: "com.android.bar",
2348		}
2349
2350		override_android_test {
2351			name: "baz_test",
2352			base: "foo_test",
2353			package_name: "com.android.baz.test",
2354			mainline_package_name: "com.android.baz",
2355		}
2356		`)
2357
2358	testCases := []struct {
2359		moduleName    string
2360		variantName   string
2361		expectedFlags []string
2362	}{
2363		{
2364			moduleName:  "foo_test",
2365			variantName: "android_common",
2366		},
2367		{
2368			moduleName:  "bar_test",
2369			variantName: "android_common",
2370			expectedFlags: []string{
2371				"--manifest out/soong/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml",
2372				"--package-name com.android.bar.test",
2373				"--mainline-package-name com.android.bar",
2374			},
2375		},
2376		{
2377			moduleName:  "foo_test",
2378			variantName: "android_common_baz_test",
2379			expectedFlags: []string{
2380				"--manifest out/soong/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml",
2381				"--package-name com.android.baz.test",
2382				"--test-file-name baz_test.apk",
2383				"out/soong/.intermediates/foo_test/android_common_baz_test/test_config_fixer/AndroidTest.xml",
2384				"--mainline-package-name com.android.baz",
2385			},
2386		},
2387	}
2388
2389	for _, test := range testCases {
2390		variant := ctx.ModuleForTests(test.moduleName, test.variantName)
2391		params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml")
2392
2393		if len(test.expectedFlags) > 0 {
2394			if params.Rule == nil {
2395				t.Errorf("test_config_fixer was expected to run, but didn't")
2396			} else {
2397				for _, flag := range test.expectedFlags {
2398					if !strings.Contains(params.RuleParams.Command, flag) {
2399						t.Errorf("Flag %q was not found in command: %q", flag, params.RuleParams.Command)
2400					}
2401				}
2402			}
2403		} else {
2404			if params.Rule != nil {
2405				t.Errorf("test_config_fixer was not expected to run, but did: %q", params.RuleParams.Command)
2406			}
2407		}
2408	}
2409}
2410
2411func TestInstrumentationTargetPrebuilt(t *testing.T) {
2412	bp := `
2413		android_app_import {
2414			name: "foo",
2415			apk: "foo.apk",
2416			presigned: true,
2417		}
2418
2419		android_test {
2420			name: "bar",
2421			srcs: ["a.java"],
2422			instrumentation_for: "foo",
2423			sdk_version: "current",
2424		}
2425		`
2426
2427	android.GroupFixturePreparers(
2428		PrepareForTestWithJavaDefaultModules,
2429	).ExtendWithErrorHandler(
2430		android.FixtureExpectsAtLeastOneErrorMatchingPattern(
2431			"instrumentation_for: dependency \"foo\" of type \"android_app_import\" does not provide JavaInfo so is unsuitable for use with this property")).
2432		RunTestWithBp(t, bp)
2433}
2434
2435func TestStl(t *testing.T) {
2436	ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
2437		cc_library {
2438			name: "libjni",
2439			sdk_version: "current",
2440			stl: "c++_shared",
2441		}
2442
2443		android_test {
2444			name: "stl",
2445			jni_libs: ["libjni"],
2446			compile_multilib: "both",
2447			sdk_version: "current",
2448			stl: "c++_shared",
2449		}
2450
2451		android_test {
2452			name: "system",
2453			jni_libs: ["libjni"],
2454			compile_multilib: "both",
2455			sdk_version: "current",
2456		}
2457		`)
2458
2459	testCases := []struct {
2460		name string
2461		jnis []string
2462	}{
2463		{"stl",
2464			[]string{
2465				"libjni.so",
2466				"libc++_shared.so",
2467			},
2468		},
2469		{"system",
2470			[]string{
2471				"libjni.so",
2472			},
2473		},
2474	}
2475
2476	for _, test := range testCases {
2477		t.Run(test.name, func(t *testing.T) {
2478			app := ctx.ModuleForTests(test.name, "android_common")
2479			jniLibZip := app.Output(jniJarOutputPathString)
2480			var jnis []string
2481			args := strings.Fields(jniLibZip.Args["jarArgs"])
2482			for i := 0; i < len(args); i++ {
2483				if args[i] == "-f" {
2484					jnis = append(jnis, args[i+1])
2485					i += 1
2486				}
2487			}
2488			jnisJoined := strings.Join(jnis, " ")
2489			for _, jni := range test.jnis {
2490				if !strings.Contains(jnisJoined, jni) {
2491					t.Errorf("missing jni %q in %q", jni, jnis)
2492				}
2493			}
2494		})
2495	}
2496}
2497
2498func TestUsesLibraries(t *testing.T) {
2499	bp := `
2500		java_sdk_library {
2501			name: "foo",
2502			srcs: ["a.java"],
2503			api_packages: ["foo"],
2504			sdk_version: "current",
2505		}
2506
2507		java_sdk_library {
2508			name: "qux",
2509			srcs: ["a.java"],
2510			api_packages: ["qux"],
2511			sdk_version: "current",
2512		}
2513
2514		java_sdk_library {
2515			name: "quuz",
2516			srcs: ["a.java"],
2517			api_packages: ["quuz"],
2518			sdk_version: "current",
2519		}
2520
2521		java_sdk_library {
2522			name: "fred",
2523			srcs: ["a.java"],
2524			api_packages: ["fred"],
2525			sdk_version: "current",
2526		}
2527
2528		java_sdk_library {
2529			name: "bar",
2530			srcs: ["a.java"],
2531			api_packages: ["bar"],
2532			sdk_version: "current",
2533		}
2534
2535		java_sdk_library {
2536			name: "runtime-library",
2537			srcs: ["a.java"],
2538			sdk_version: "current",
2539		}
2540
2541		java_library {
2542			name: "static-runtime-helper",
2543			srcs: ["a.java"],
2544			libs: ["runtime-library"],
2545			sdk_version: "current",
2546		}
2547
2548		java_library {
2549			name: "runtime-required-x",
2550			srcs: ["a.java"],
2551			installable: true,
2552			sdk_version: "current",
2553		}
2554
2555		java_library {
2556			name: "runtime-optional-x",
2557			srcs: ["a.java"],
2558			installable: true,
2559			sdk_version: "current",
2560		}
2561
2562		android_library {
2563			name: "static-x",
2564			uses_libs: ["runtime-required-x"],
2565			optional_uses_libs: ["runtime-optional-x"],
2566			sdk_version: "current",
2567		}
2568
2569		java_library {
2570			name: "runtime-required-y",
2571			srcs: ["a.java"],
2572			installable: true,
2573			sdk_version: "current",
2574		}
2575
2576		java_library {
2577			name: "runtime-optional-y",
2578			srcs: ["a.java"],
2579			installable: true,
2580			sdk_version: "current",
2581		}
2582
2583		java_library {
2584			name: "static-y",
2585			srcs: ["a.java"],
2586			uses_libs: ["runtime-required-y"],
2587			optional_uses_libs: ["runtime-optional-y"],
2588			sdk_version: "current",
2589		}
2590
2591		// A library that has to use "provides_uses_lib", because:
2592		//    - it is not an SDK library
2593		//    - its library name is different from its module name
2594		java_library {
2595			name: "non-sdk-lib",
2596			provides_uses_lib: "com.non.sdk.lib",
2597			installable: true,
2598			srcs: ["a.java"],
2599		}
2600
2601		android_app {
2602			name: "app",
2603			srcs: ["a.java"],
2604			libs: [
2605				"qux",
2606				"quuz.stubs"
2607			],
2608			static_libs: [
2609				"static-runtime-helper",
2610				// statically linked component libraries should not pull their SDK libraries,
2611				// so "fred" should not be added to class loader context
2612				"fred.stubs",
2613				"static-x",
2614				"static-y",
2615			],
2616			uses_libs: [
2617				"foo",
2618				"non-sdk-lib"
2619			],
2620			sdk_version: "current",
2621			optional_uses_libs: [
2622				"bar",
2623				"baz",
2624			],
2625		}
2626
2627		android_app_import {
2628			name: "prebuilt",
2629			apk: "prebuilts/apk/app.apk",
2630			certificate: "platform",
2631			uses_libs: [
2632				"foo",
2633				"non-sdk-lib",
2634				"android.test.runner"
2635			],
2636			optional_uses_libs: [
2637				"bar",
2638				"baz",
2639			],
2640		}
2641	`
2642
2643	result := android.GroupFixturePreparers(
2644		prepareForJavaTest,
2645		PrepareForTestWithJavaSdkLibraryFiles,
2646		FixtureWithLastReleaseApis("runtime-library", "foo", "quuz", "qux", "bar", "fred"),
2647		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2648			variables.MissingUsesLibraries = []string{"baz"}
2649		}),
2650	).RunTestWithBp(t, bp)
2651
2652	app := result.ModuleForTests("app", "android_common")
2653	prebuilt := result.ModuleForTests("prebuilt", "android_common")
2654
2655	// Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
2656	// These also include explicit `uses_libs`/`optional_uses_libs` entries, as they may be
2657	// propagated from dependencies.
2658	actualManifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
2659	expectManifestFixerArgs := `--extract-native-libs=true ` +
2660		`--uses-library qux ` +
2661		`--uses-library quuz ` +
2662		`--uses-library foo ` +
2663		`--uses-library com.non.sdk.lib ` +
2664		`--uses-library runtime-library ` +
2665		`--uses-library runtime-required-x ` +
2666		`--uses-library runtime-required-y ` +
2667		`--optional-uses-library bar ` +
2668		`--optional-uses-library runtime-optional-x ` +
2669		`--optional-uses-library runtime-optional-y`
2670	android.AssertStringDoesContain(t, "manifest_fixer args", actualManifestFixerArgs, expectManifestFixerArgs)
2671
2672	// Test that all libraries are verified (library order matters).
2673	verifyCmd := app.Rule("verify_uses_libraries").RuleParams.Command
2674	verifyArgs := `--uses-library foo ` +
2675		`--uses-library com.non.sdk.lib ` +
2676		`--uses-library qux ` +
2677		`--uses-library quuz ` +
2678		`--uses-library runtime-library ` +
2679		`--uses-library runtime-required-x ` +
2680		`--uses-library runtime-required-y ` +
2681		`--optional-uses-library bar ` +
2682		`--optional-uses-library baz ` +
2683		`--optional-uses-library runtime-optional-x ` +
2684		`--optional-uses-library runtime-optional-y `
2685	android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs)
2686
2687	// Test that all libraries are verified for an APK (library order matters).
2688	verifyApkCmd := prebuilt.Rule("verify_uses_libraries").RuleParams.Command
2689	verifyApkArgs := `--uses-library foo ` +
2690		`--uses-library com.non.sdk.lib ` +
2691		`--uses-library android.test.runner ` +
2692		`--optional-uses-library bar ` +
2693		`--optional-uses-library baz `
2694	android.AssertStringDoesContain(t, "verify apk cmd args", verifyApkCmd, verifyApkArgs)
2695
2696	// Test that all present libraries are preopted, including implicit SDK dependencies, possibly stubs
2697	cmd := app.Rule("dexpreopt").RuleParams.Command
2698	w := `--target-context-for-sdk any ` +
2699		`PCL[/system/framework/qux.jar]#` +
2700		`PCL[/system/framework/quuz.jar]#` +
2701		`PCL[/system/framework/foo.jar]#` +
2702		`PCL[/system/framework/non-sdk-lib.jar]#` +
2703		`PCL[/system/framework/bar.jar]#` +
2704		`PCL[/system/framework/runtime-library.jar]#` +
2705		`PCL[/system/framework/runtime-required-x.jar]#` +
2706		`PCL[/system/framework/runtime-optional-x.jar]#` +
2707		`PCL[/system/framework/runtime-required-y.jar]#` +
2708		`PCL[/system/framework/runtime-optional-y.jar] `
2709	android.AssertStringDoesContain(t, "dexpreopt app cmd args", cmd, w)
2710
2711	// Test conditional context for target SDK version 28.
2712	android.AssertStringDoesContain(t, "dexpreopt app cmd 28", cmd,
2713		`--target-context-for-sdk 28`+
2714			` PCL[/system/framework/org.apache.http.legacy.jar] `)
2715
2716	// Test conditional context for target SDK version 29.
2717	android.AssertStringDoesContain(t, "dexpreopt app cmd 29", cmd,
2718		`--target-context-for-sdk 29`+
2719			` PCL[/system/framework/android.hidl.manager-V1.0-java.jar]`+
2720			`#PCL[/system/framework/android.hidl.base-V1.0-java.jar] `)
2721
2722	// Test conditional context for target SDK version 30.
2723	// "android.test.mock" is absent because "android.test.runner" is not used.
2724	android.AssertStringDoesContain(t, "dexpreopt app cmd 30", cmd,
2725		`--target-context-for-sdk 30`+
2726			` PCL[/system/framework/android.test.base.jar] `)
2727
2728	cmd = prebuilt.Rule("dexpreopt").RuleParams.Command
2729	android.AssertStringDoesContain(t, "dexpreopt prebuilt cmd", cmd,
2730		`--target-context-for-sdk any`+
2731			` PCL[/system/framework/foo.jar]`+
2732			`#PCL[/system/framework/non-sdk-lib.jar]`+
2733			`#PCL[/system/framework/android.test.runner.jar]`+
2734			`#PCL[/system/framework/bar.jar] `)
2735
2736	// Test conditional context for target SDK version 30.
2737	// "android.test.mock" is present because "android.test.runner" is used.
2738	android.AssertStringDoesContain(t, "dexpreopt prebuilt cmd 30", cmd,
2739		`--target-context-for-sdk 30`+
2740			` PCL[/system/framework/android.test.base.jar]`+
2741			`#PCL[/system/framework/android.test.mock.jar] `)
2742}
2743
2744func TestDexpreoptBcp(t *testing.T) {
2745	bp := `
2746		java_sdk_library {
2747			name: "foo",
2748			srcs: ["a.java"],
2749			api_packages: ["foo"],
2750			sdk_version: "current",
2751		}
2752
2753		java_sdk_library {
2754			name: "bar",
2755			srcs: ["a.java"],
2756			api_packages: ["bar"],
2757			permitted_packages: ["bar"],
2758			sdk_version: "current",
2759		}
2760
2761		android_app {
2762			name: "app",
2763			srcs: ["a.java"],
2764			sdk_version: "current",
2765		}
2766	`
2767
2768	testCases := []struct {
2769		name   string
2770		with   bool
2771		expect string
2772	}{
2773		{
2774			name:   "with updatable bcp",
2775			with:   true,
2776			expect: "/system/framework/foo.jar:/system/framework/bar.jar",
2777		},
2778		{
2779			name:   "without updatable bcp",
2780			with:   false,
2781			expect: "/system/framework/foo.jar",
2782		},
2783	}
2784
2785	for _, test := range testCases {
2786		t.Run(test.name, func(t *testing.T) {
2787			result := android.GroupFixturePreparers(
2788				prepareForJavaTest,
2789				PrepareForTestWithJavaSdkLibraryFiles,
2790				FixtureWithLastReleaseApis("runtime-library", "foo", "bar"),
2791				dexpreopt.FixtureSetBootJars("platform:foo"),
2792				dexpreopt.FixtureSetApexBootJars("platform:bar"),
2793				dexpreopt.FixtureSetPreoptWithUpdatableBcp(test.with),
2794			).RunTestWithBp(t, bp)
2795
2796			app := result.ModuleForTests("app", "android_common")
2797			cmd := app.Rule("dexpreopt").RuleParams.Command
2798			bcp := " -Xbootclasspath-locations:" + test.expect + " " // space at the end matters
2799			android.AssertStringDoesContain(t, "dexpreopt app bcp", cmd, bcp)
2800		})
2801	}
2802}
2803
2804func TestCodelessApp(t *testing.T) {
2805	testCases := []struct {
2806		name   string
2807		bp     string
2808		noCode bool
2809	}{
2810		{
2811			name: "normal",
2812			bp: `
2813				android_app {
2814					name: "foo",
2815					srcs: ["a.java"],
2816					sdk_version: "current",
2817				}
2818			`,
2819			noCode: false,
2820		},
2821		{
2822			name: "app without sources",
2823			bp: `
2824				android_app {
2825					name: "foo",
2826					sdk_version: "current",
2827				}
2828			`,
2829			noCode: true,
2830		},
2831		{
2832			name: "app with libraries",
2833			bp: `
2834				android_app {
2835					name: "foo",
2836					static_libs: ["lib"],
2837					sdk_version: "current",
2838				}
2839
2840				java_library {
2841					name: "lib",
2842					srcs: ["a.java"],
2843					sdk_version: "current",
2844				}
2845			`,
2846			noCode: false,
2847		},
2848		{
2849			name: "app with sourceless libraries",
2850			bp: `
2851				android_app {
2852					name: "foo",
2853					static_libs: ["lib"],
2854					sdk_version: "current",
2855				}
2856
2857				java_library {
2858					name: "lib",
2859					sdk_version: "current",
2860				}
2861			`,
2862			// TODO(jungjw): this should probably be true
2863			noCode: false,
2864		},
2865	}
2866
2867	for _, test := range testCases {
2868		t.Run(test.name, func(t *testing.T) {
2869			ctx := testApp(t, test.bp)
2870
2871			foo := ctx.ModuleForTests("foo", "android_common")
2872			manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
2873			if strings.Contains(manifestFixerArgs, "--has-no-code") != test.noCode {
2874				t.Errorf("unexpected manifest_fixer args: %q", manifestFixerArgs)
2875			}
2876		})
2877	}
2878}
2879
2880func TestUncompressDex(t *testing.T) {
2881	testCases := []struct {
2882		name string
2883		bp   string
2884
2885		uncompressedPlatform  bool
2886		uncompressedUnbundled bool
2887	}{
2888		{
2889			name: "normal",
2890			bp: `
2891				android_app {
2892					name: "foo",
2893					srcs: ["a.java"],
2894					sdk_version: "current",
2895				}
2896			`,
2897			uncompressedPlatform:  true,
2898			uncompressedUnbundled: false,
2899		},
2900		{
2901			name: "use_embedded_dex",
2902			bp: `
2903				android_app {
2904					name: "foo",
2905					use_embedded_dex: true,
2906					srcs: ["a.java"],
2907					sdk_version: "current",
2908				}
2909			`,
2910			uncompressedPlatform:  true,
2911			uncompressedUnbundled: true,
2912		},
2913		{
2914			name: "privileged",
2915			bp: `
2916				android_app {
2917					name: "foo",
2918					privileged: true,
2919					srcs: ["a.java"],
2920					sdk_version: "current",
2921				}
2922			`,
2923			uncompressedPlatform:  true,
2924			uncompressedUnbundled: true,
2925		},
2926		{
2927			name: "normal_uncompress_dex_true",
2928			bp: `
2929				android_app {
2930					name: "foo",
2931					srcs: ["a.java"],
2932					sdk_version: "current",
2933					uncompress_dex: true,
2934				}
2935			`,
2936			uncompressedPlatform:  true,
2937			uncompressedUnbundled: true,
2938		},
2939		{
2940			name: "normal_uncompress_dex_false",
2941			bp: `
2942				android_app {
2943					name: "foo",
2944					srcs: ["a.java"],
2945					sdk_version: "current",
2946					uncompress_dex: false,
2947				}
2948			`,
2949			uncompressedPlatform:  false,
2950			uncompressedUnbundled: false,
2951		},
2952	}
2953
2954	test := func(t *testing.T, bp string, want bool, unbundled bool) {
2955		t.Helper()
2956
2957		result := android.GroupFixturePreparers(
2958			prepareForJavaTest,
2959			PrepareForTestWithPrebuiltsOfCurrentApi,
2960			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2961				if unbundled {
2962					variables.Unbundled_build = proptools.BoolPtr(true)
2963					variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
2964				}
2965			}),
2966		).RunTestWithBp(t, bp)
2967
2968		foo := result.ModuleForTests("foo", "android_common")
2969		dex := foo.Rule("r8")
2970		uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0")
2971		aligned := foo.MaybeRule("zipalign").Rule != nil
2972
2973		android.AssertBoolEquals(t, "uncompressed in dex", want, uncompressedInDexJar)
2974
2975		android.AssertBoolEquals(t, "aligne", want, aligned)
2976	}
2977
2978	for _, tt := range testCases {
2979		t.Run(tt.name, func(t *testing.T) {
2980			t.Run("platform", func(t *testing.T) {
2981				test(t, tt.bp, tt.uncompressedPlatform, false)
2982			})
2983			t.Run("unbundled", func(t *testing.T) {
2984				test(t, tt.bp, tt.uncompressedUnbundled, true)
2985			})
2986		})
2987	}
2988}
2989
2990func checkAapt2LinkFlag(t *testing.T, aapt2Flags, flagName, expectedValue string) {
2991	if expectedValue != "" {
2992		expectedFlag := "--" + flagName + " " + expectedValue
2993		if !strings.Contains(aapt2Flags, expectedFlag) {
2994			t.Errorf("%q is missing in aapt2 link flags, %q", expectedFlag, aapt2Flags)
2995		}
2996	} else {
2997		unexpectedFlag := "--" + flagName
2998		if strings.Contains(aapt2Flags, unexpectedFlag) {
2999			t.Errorf("unexpected flag, %q is found in aapt2 link flags, %q", unexpectedFlag, aapt2Flags)
3000		}
3001	}
3002}
3003
3004func TestExportedProguardFlagFiles(t *testing.T) {
3005	ctx, _ := testJava(t, `
3006		android_app {
3007			name: "foo",
3008			sdk_version: "current",
3009			static_libs: ["lib1"],
3010		}
3011
3012		android_library {
3013			name: "lib1",
3014			sdk_version: "current",
3015			optimize: {
3016				proguard_flags_files: ["lib1proguard.cfg"],
3017			}
3018		}
3019	`)
3020
3021	m := ctx.ModuleForTests("foo", "android_common")
3022	hasLib1Proguard := false
3023	for _, s := range m.Rule("java.r8").Implicits.Strings() {
3024		if s == "lib1proguard.cfg" {
3025			hasLib1Proguard = true
3026			break
3027		}
3028	}
3029
3030	if !hasLib1Proguard {
3031		t.Errorf("App does not use library proguard config")
3032	}
3033}
3034
3035func TestTargetSdkVersionManifestFixer(t *testing.T) {
3036	platform_sdk_codename := "Tiramisu"
3037	platform_sdk_version := 33
3038	testCases := []struct {
3039		name                     string
3040		targetSdkVersionInBp     string
3041		targetSdkVersionExpected string
3042		unbundledBuild           bool
3043		platformSdkFinal         bool
3044	}{
3045		{
3046			name:                     "Non-Unbundled build: Android.bp has targetSdkVersion",
3047			targetSdkVersionInBp:     "30",
3048			targetSdkVersionExpected: "30",
3049			unbundledBuild:           false,
3050		},
3051		{
3052			name:                     "Unbundled build: Android.bp has targetSdkVersion",
3053			targetSdkVersionInBp:     "30",
3054			targetSdkVersionExpected: "30",
3055			unbundledBuild:           true,
3056		},
3057		{
3058			name:                     "Non-Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename",
3059			targetSdkVersionInBp:     platform_sdk_codename,
3060			targetSdkVersionExpected: platform_sdk_codename,
3061			unbundledBuild:           false,
3062		},
3063		{
3064			name:                     "Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename",
3065			targetSdkVersionInBp:     platform_sdk_codename,
3066			targetSdkVersionExpected: "10000",
3067			unbundledBuild:           true,
3068		},
3069
3070		{
3071			name:                     "Non-Unbundled build: Android.bp has no targetSdkVersion",
3072			targetSdkVersionExpected: platform_sdk_codename,
3073			unbundledBuild:           false,
3074		},
3075		{
3076			name:                     "Unbundled build: Android.bp has no targetSdkVersion",
3077			targetSdkVersionExpected: "10000",
3078			unbundledBuild:           true,
3079		},
3080		{
3081			name:                     "Bundled build in REL branches",
3082			targetSdkVersionExpected: "33",
3083			unbundledBuild:           false,
3084			platformSdkFinal:         true,
3085		},
3086	}
3087	for _, testCase := range testCases {
3088		targetSdkVersionTemplate := ""
3089		if testCase.targetSdkVersionInBp != "" {
3090			targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, testCase.targetSdkVersionInBp)
3091		}
3092		bp := fmt.Sprintf(`
3093			android_app {
3094				name: "foo",
3095				sdk_version: "current",
3096				%s
3097			}
3098			`, targetSdkVersionTemplate)
3099		fixture := android.GroupFixturePreparers(
3100			prepareForJavaTest,
3101			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3102				if testCase.platformSdkFinal {
3103					variables.Platform_sdk_final = proptools.BoolPtr(true)
3104				}
3105				// explicitly set platform_sdk_codename to make the test deterministic
3106				variables.Platform_sdk_codename = &platform_sdk_codename
3107				variables.Platform_sdk_version = &platform_sdk_version
3108				variables.Platform_version_active_codenames = []string{platform_sdk_codename}
3109				// create a non-empty list if unbundledBuild==true
3110				if testCase.unbundledBuild {
3111					variables.Unbundled_build_apps = []string{"apex_a", "apex_b"}
3112				}
3113			}),
3114		)
3115
3116		result := fixture.RunTestWithBp(t, bp)
3117		foo := result.ModuleForTests("foo", "android_common")
3118
3119		manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
3120		android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion  "+testCase.targetSdkVersionExpected)
3121	}
3122}
3123
3124func TestDefaultAppTargetSdkVersionForUpdatableModules(t *testing.T) {
3125	platform_sdk_codename := "Tiramisu"
3126	platform_sdk_version := 33
3127	testCases := []struct {
3128		name                     string
3129		platform_sdk_final       bool
3130		targetSdkVersionInBp     *string
3131		targetSdkVersionExpected *string
3132		updatable                bool
3133	}{
3134		{
3135			name:                     "Non-Updatable Module: Android.bp has older targetSdkVersion",
3136			targetSdkVersionInBp:     proptools.StringPtr("29"),
3137			targetSdkVersionExpected: proptools.StringPtr("29"),
3138			updatable:                false,
3139		},
3140		{
3141			name:                     "Updatable Module: Android.bp has older targetSdkVersion",
3142			targetSdkVersionInBp:     proptools.StringPtr("30"),
3143			targetSdkVersionExpected: proptools.StringPtr("30"),
3144			updatable:                true,
3145		},
3146		{
3147			name:                     "Updatable Module: Android.bp has no targetSdkVersion",
3148			targetSdkVersionExpected: proptools.StringPtr("10000"),
3149			updatable:                true,
3150		},
3151		{
3152			name:                     "[SDK finalised] Non-Updatable Module: Android.bp has older targetSdkVersion",
3153			platform_sdk_final:       true,
3154			targetSdkVersionInBp:     proptools.StringPtr("30"),
3155			targetSdkVersionExpected: proptools.StringPtr("30"),
3156			updatable:                false,
3157		},
3158		{
3159			name:                     "[SDK finalised] Updatable Module: Android.bp has older targetSdkVersion",
3160			platform_sdk_final:       true,
3161			targetSdkVersionInBp:     proptools.StringPtr("30"),
3162			targetSdkVersionExpected: proptools.StringPtr("30"),
3163			updatable:                true,
3164		},
3165		{
3166			name:                     "[SDK finalised] Updatable Module: Android.bp has targetSdkVersion as platform sdk codename",
3167			platform_sdk_final:       true,
3168			targetSdkVersionInBp:     proptools.StringPtr(platform_sdk_codename),
3169			targetSdkVersionExpected: proptools.StringPtr("33"),
3170			updatable:                true,
3171		},
3172		{
3173			name:                     "[SDK finalised] Updatable Module: Android.bp has no targetSdkVersion",
3174			platform_sdk_final:       true,
3175			targetSdkVersionExpected: proptools.StringPtr("33"),
3176			updatable:                true,
3177		},
3178	}
3179	for _, testCase := range testCases {
3180		targetSdkVersionTemplate := ""
3181		if testCase.targetSdkVersionInBp != nil {
3182			targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, *testCase.targetSdkVersionInBp)
3183		}
3184		bp := fmt.Sprintf(`
3185			android_app {
3186				name: "foo",
3187				sdk_version: "current",
3188				min_sdk_version: "29",
3189				%s
3190				updatable: %t,
3191				enforce_default_target_sdk_version: %t
3192			}
3193			`, targetSdkVersionTemplate, testCase.updatable, testCase.updatable) // enforce default target sdk version if app is updatable
3194
3195		fixture := android.GroupFixturePreparers(
3196			PrepareForTestWithJavaDefaultModules,
3197			android.PrepareForTestWithAllowMissingDependencies,
3198			android.PrepareForTestWithAndroidMk,
3199			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3200				// explicitly set following platform variables to make the test deterministic
3201				variables.Platform_sdk_final = &testCase.platform_sdk_final
3202				variables.Platform_sdk_version = &platform_sdk_version
3203				variables.Platform_sdk_codename = &platform_sdk_codename
3204				variables.Platform_version_active_codenames = []string{platform_sdk_codename}
3205				variables.Unbundled_build = proptools.BoolPtr(true)
3206				variables.Unbundled_build_apps = []string{"sampleModule"}
3207			}),
3208		)
3209
3210		result := fixture.RunTestWithBp(t, bp)
3211		foo := result.ModuleForTests("foo", "android_common")
3212
3213		manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
3214		android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion  "+*testCase.targetSdkVersionExpected)
3215	}
3216}
3217
3218func TestEnforceDefaultAppTargetSdkVersionFlag(t *testing.T) {
3219	platform_sdk_codename := "Tiramisu"
3220	platform_sdk_version := 33
3221	testCases := []struct {
3222		name                           string
3223		enforceDefaultTargetSdkVersion bool
3224		expectedError                  string
3225		platform_sdk_final             bool
3226		targetSdkVersionInBp           string
3227		targetSdkVersionExpected       string
3228		updatable                      bool
3229	}{
3230		{
3231			name:                           "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion",
3232			enforceDefaultTargetSdkVersion: false,
3233			targetSdkVersionInBp:           "29",
3234			targetSdkVersionExpected:       "29",
3235			updatable:                      false,
3236		},
3237		{
3238			name:                           "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
3239			enforceDefaultTargetSdkVersion: true,
3240			platform_sdk_final:             true,
3241			targetSdkVersionInBp:           "current",
3242			targetSdkVersionExpected:       "33",
3243			updatable:                      true,
3244		},
3245		{
3246			name:                           "Enforce Target SDK Version: Android.bp has current targetSdkVersion",
3247			enforceDefaultTargetSdkVersion: true,
3248			platform_sdk_final:             false,
3249			targetSdkVersionInBp:           "current",
3250			targetSdkVersionExpected:       "10000",
3251			updatable:                      false,
3252		},
3253		{
3254			name:                           "Not enforcing Target SDK Version for Updatable app",
3255			enforceDefaultTargetSdkVersion: false,
3256			expectedError:                  "Updatable apps must enforce default target sdk version",
3257			targetSdkVersionInBp:           "29",
3258			targetSdkVersionExpected:       "29",
3259			updatable:                      true,
3260		},
3261	}
3262	for _, testCase := range testCases {
3263		errExpected := testCase.expectedError != ""
3264		bp := fmt.Sprintf(`
3265			android_app {
3266				name: "foo",
3267				enforce_default_target_sdk_version: %t,
3268				sdk_version: "current",
3269				min_sdk_version: "29",
3270				target_sdk_version: "%v",
3271				updatable: %t
3272			}
3273			`, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp, testCase.updatable)
3274
3275		fixture := android.GroupFixturePreparers(
3276			PrepareForTestWithJavaDefaultModules,
3277			android.PrepareForTestWithAllowMissingDependencies,
3278			android.PrepareForTestWithAndroidMk,
3279			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3280				// explicitly set following platform variables to make the test deterministic
3281				variables.Platform_sdk_final = &testCase.platform_sdk_final
3282				variables.Platform_sdk_version = &platform_sdk_version
3283				variables.Platform_sdk_codename = &platform_sdk_codename
3284				variables.Unbundled_build = proptools.BoolPtr(true)
3285				variables.Unbundled_build_apps = []string{"sampleModule"}
3286			}),
3287		)
3288
3289		errorHandler := android.FixtureExpectsNoErrors
3290		if errExpected {
3291			errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
3292		}
3293		result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
3294
3295		if !errExpected {
3296			foo := result.ModuleForTests("foo", "android_common")
3297			manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
3298			android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion  "+testCase.targetSdkVersionExpected)
3299		}
3300	}
3301}
3302
3303func TestEnforceDefaultAppTargetSdkVersionFlagForTests(t *testing.T) {
3304	platform_sdk_codename := "Tiramisu"
3305	platform_sdk_version := 33
3306	testCases := []struct {
3307		name                           string
3308		enforceDefaultTargetSdkVersion bool
3309		expectedError                  string
3310		platform_sdk_final             bool
3311		targetSdkVersionInBp           string
3312		targetSdkVersionExpected       string
3313	}{
3314		{
3315			name:                           "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion",
3316			enforceDefaultTargetSdkVersion: false,
3317			targetSdkVersionInBp:           "29",
3318			targetSdkVersionExpected:       "29",
3319		},
3320		{
3321			name:                           "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
3322			enforceDefaultTargetSdkVersion: true,
3323			platform_sdk_final:             true,
3324			targetSdkVersionInBp:           "current",
3325			targetSdkVersionExpected:       "33",
3326		},
3327		{
3328			name:                           "Enforce Target SDK Version: Android.bp has current targetSdkVersion",
3329			enforceDefaultTargetSdkVersion: true,
3330			platform_sdk_final:             false,
3331			targetSdkVersionInBp:           "current",
3332			targetSdkVersionExpected:       "10000",
3333		},
3334	}
3335	for _, testCase := range testCases {
3336		errExpected := testCase.expectedError != ""
3337		bp := fmt.Sprintf(`
3338			android_test {
3339				name: "foo",
3340				enforce_default_target_sdk_version: %t,
3341				min_sdk_version: "29",
3342				target_sdk_version: "%v",
3343			}
3344		`, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp)
3345
3346		fixture := android.GroupFixturePreparers(
3347			PrepareForTestWithJavaDefaultModules,
3348			android.PrepareForTestWithAllowMissingDependencies,
3349			android.PrepareForTestWithAndroidMk,
3350			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3351				// explicitly set following platform variables to make the test deterministic
3352				variables.Platform_sdk_final = &testCase.platform_sdk_final
3353				variables.Platform_sdk_version = &platform_sdk_version
3354				variables.Platform_sdk_codename = &platform_sdk_codename
3355				variables.Unbundled_build = proptools.BoolPtr(true)
3356				variables.Unbundled_build_apps = []string{"sampleModule"}
3357			}),
3358		)
3359
3360		errorHandler := android.FixtureExpectsNoErrors
3361		if errExpected {
3362			errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
3363		}
3364		result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
3365
3366		if !errExpected {
3367			foo := result.ModuleForTests("foo", "android_common")
3368			manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
3369			android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion  "+testCase.targetSdkVersionExpected)
3370		}
3371	}
3372}
3373
3374func TestAppMissingCertificateAllowMissingDependencies(t *testing.T) {
3375	result := android.GroupFixturePreparers(
3376		PrepareForTestWithJavaDefaultModules,
3377		android.PrepareForTestWithAllowMissingDependencies,
3378		android.PrepareForTestWithAndroidMk,
3379	).RunTestWithBp(t, `
3380		android_app {
3381			name: "foo",
3382			srcs: ["a.java"],
3383			certificate: ":missing_certificate",
3384			sdk_version: "current",
3385		}
3386
3387		android_app {
3388			name: "bar",
3389			srcs: ["a.java"],
3390			certificate: ":missing_certificate",
3391			product_specific: true,
3392			sdk_version: "current",
3393		}`)
3394
3395	foo := result.ModuleForTests("foo", "android_common")
3396	fooApk := foo.Output("foo.apk")
3397	if fooApk.Rule != android.ErrorRule {
3398		t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String())
3399	}
3400	android.AssertStringDoesContain(t, "expected error rule message", fooApk.Args["error"], "missing dependencies: missing_certificate\n")
3401}
3402
3403func TestAppIncludesJniPackages(t *testing.T) {
3404	ctx := android.GroupFixturePreparers(
3405		PrepareForTestWithJavaDefaultModules,
3406	).RunTestWithBp(t, `
3407		android_library_import {
3408			name: "aary-nodeps",
3409			aars: ["aary.aar"],
3410			extract_jni: true,
3411		}
3412
3413		android_library {
3414			name: "aary-lib",
3415			sdk_version: "current",
3416			min_sdk_version: "21",
3417			static_libs: ["aary-nodeps"],
3418		}
3419
3420		android_app {
3421			name: "aary-lib-dep",
3422			sdk_version: "current",
3423			min_sdk_version: "21",
3424			manifest: "AndroidManifest.xml",
3425			static_libs: ["aary-lib"],
3426			use_embedded_native_libs: true,
3427		}
3428
3429		android_app {
3430			name: "aary-import-dep",
3431			sdk_version: "current",
3432			min_sdk_version: "21",
3433			manifest: "AndroidManifest.xml",
3434			static_libs: ["aary-nodeps"],
3435			use_embedded_native_libs: true,
3436		}
3437
3438		android_app {
3439			name: "aary-no-use-embedded",
3440			sdk_version: "current",
3441			min_sdk_version: "21",
3442			manifest: "AndroidManifest.xml",
3443			static_libs: ["aary-nodeps"],
3444		}`)
3445
3446	testCases := []struct {
3447		name       string
3448		hasPackage bool
3449	}{
3450		{
3451			name:       "aary-import-dep",
3452			hasPackage: true,
3453		},
3454		{
3455			name:       "aary-lib-dep",
3456			hasPackage: true,
3457		},
3458		{
3459			name:       "aary-no-use-embedded",
3460			hasPackage: false,
3461		},
3462	}
3463
3464	for _, tc := range testCases {
3465		t.Run(tc.name, func(t *testing.T) {
3466			app := ctx.ModuleForTests(tc.name, "android_common")
3467
3468			outputFile := "jnilibs.zip"
3469			jniOutputLibZip := app.MaybeOutput(outputFile)
3470			if jniOutputLibZip.Rule == nil && !tc.hasPackage {
3471				return
3472			}
3473
3474			jniPackage := "arm64-v8a_jni.zip"
3475			inputs := jniOutputLibZip.Inputs
3476			foundPackage := false
3477			for i := 0; i < len(inputs); i++ {
3478				if strings.Contains(inputs[i].String(), jniPackage) {
3479					foundPackage = true
3480				}
3481			}
3482			if foundPackage != tc.hasPackage {
3483				t.Errorf("expected to find %v in %v inputs; inputs = %v", jniPackage, outputFile, inputs)
3484			}
3485		})
3486	}
3487}
3488
3489func TestTargetSdkVersionMtsTests(t *testing.T) {
3490	platformSdkCodename := "Tiramisu"
3491	android_test := "android_test"
3492	android_test_helper_app := "android_test_helper_app"
3493	bpTemplate := `
3494	%v {
3495		name: "mytest",
3496		target_sdk_version: "%v",
3497		test_suites: ["othersuite", "%v"],
3498	}
3499	`
3500	testCases := []struct {
3501		desc                     string
3502		moduleType               string
3503		targetSdkVersionInBp     string
3504		targetSdkVersionExpected string
3505		testSuites               string
3506	}{
3507		{
3508			desc:                     "Non-MTS android_test_apps targeting current should not be upgraded to 10000",
3509			moduleType:               android_test,
3510			targetSdkVersionInBp:     "current",
3511			targetSdkVersionExpected: platformSdkCodename,
3512			testSuites:               "non-mts-suite",
3513		},
3514		{
3515			desc:                     "MTS android_test_apps targeting released sdks should not be upgraded to 10000",
3516			moduleType:               android_test,
3517			targetSdkVersionInBp:     "29",
3518			targetSdkVersionExpected: "29",
3519			testSuites:               "mts-suite",
3520		},
3521		{
3522			desc:                     "MTS android_test_apps targeting current should be upgraded to 10000",
3523			moduleType:               android_test,
3524			targetSdkVersionInBp:     "current",
3525			targetSdkVersionExpected: "10000",
3526			testSuites:               "mts-suite",
3527		},
3528		{
3529			desc:                     "MTS android_test_helper_apps targeting current should be upgraded to 10000",
3530			moduleType:               android_test_helper_app,
3531			targetSdkVersionInBp:     "current",
3532			targetSdkVersionExpected: "10000",
3533			testSuites:               "mts-suite",
3534		},
3535	}
3536	fixture := android.GroupFixturePreparers(
3537		prepareForJavaTest,
3538		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3539			variables.Platform_sdk_codename = &platformSdkCodename
3540			variables.Platform_version_active_codenames = []string{platformSdkCodename}
3541		}),
3542	)
3543	for _, testCase := range testCases {
3544		result := fixture.RunTestWithBp(t, fmt.Sprintf(bpTemplate, testCase.moduleType, testCase.targetSdkVersionInBp, testCase.testSuites))
3545		mytest := result.ModuleForTests("mytest", "android_common")
3546		manifestFixerArgs := mytest.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
3547		android.AssertStringDoesContain(t, testCase.desc, manifestFixerArgs, "--targetSdkVersion  "+testCase.targetSdkVersionExpected)
3548	}
3549}
3550