• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2021 The Android Open Source Project
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 apex
16
17import (
18	"fmt"
19	"path"
20	"sort"
21	"strings"
22	"testing"
23
24	"android/soong/android"
25	"android/soong/dexpreopt"
26	"android/soong/java"
27
28	"github.com/google/blueprint/proptools"
29)
30
31// Contains tests for bootclasspath_fragment logic from java/bootclasspath_fragment.go as the ART
32// bootclasspath_fragment requires modules from the ART apex.
33
34var prepareForTestWithBootclasspathFragment = android.GroupFixturePreparers(
35	java.PrepareForTestWithDexpreopt,
36	PrepareForTestWithApexBuildComponents,
37)
38
39// Some additional files needed for the art apex.
40var prepareForTestWithArtApex = android.GroupFixturePreparers(
41	android.FixtureMergeMockFs(android.MockFS{
42		"com.android.art.avbpubkey":                          nil,
43		"com.android.art.pem":                                nil,
44		"system/sepolicy/apex/com.android.art-file_contexts": nil,
45	}),
46	dexpreopt.FixtureSetBootImageProfiles("art/build/boot/boot-image-profile.txt"),
47)
48
49func TestBootclasspathFragments_FragmentDependency(t *testing.T) {
50	t.Parallel()
51	result := android.GroupFixturePreparers(
52		prepareForTestWithBootclasspathFragment,
53		// Configure some libraries in the art bootclasspath_fragment and platform_bootclasspath.
54		java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
55		java.FixtureConfigureApexBootJars("someapex:foo", "someapex:bar"),
56		prepareForTestWithArtApex,
57		android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"),
58		java.PrepareForTestWithJavaSdkLibraryFiles,
59		java.FixtureWithLastReleaseApis("foo", "baz"),
60	).RunTestWithBp(t, `
61		java_sdk_library {
62			name: "foo",
63			srcs: ["b.java"],
64			shared_library: false,
65			public: {
66				enabled: true,
67			},
68			system: {
69				enabled: true,
70			},
71		}
72
73		java_library {
74			name: "bar",
75			srcs: ["b.java"],
76			installable: true,
77		}
78
79		apex {
80			name: "com.android.art",
81			key: "com.android.art.key",
82			bootclasspath_fragments: ["art-bootclasspath-fragment"],
83			updatable: false,
84		}
85
86		apex_key {
87			name: "com.android.art.key",
88			public_key: "com.android.art.avbpubkey",
89			private_key: "com.android.art.pem",
90		}
91
92		java_sdk_library {
93			name: "baz",
94			apex_available: [
95				"com.android.art",
96			],
97			srcs: ["b.java"],
98			shared_library: false,
99			public: {
100				enabled: true,
101			},
102			system: {
103				enabled: true,
104			},
105			test: {
106				enabled: true,
107			},
108			sdk_version: "core_current",
109		}
110
111		java_library {
112			name: "quuz",
113			apex_available: [
114				"com.android.art",
115			],
116			srcs: ["b.java"],
117			compile_dex: true,
118		}
119
120		bootclasspath_fragment {
121			name: "art-bootclasspath-fragment",
122			image_name: "art",
123			// Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
124			contents: ["baz", "quuz"],
125			apex_available: [
126				"com.android.art",
127			],
128			hidden_api: {
129				split_packages: ["*"],
130			},
131		}
132
133		bootclasspath_fragment {
134			name: "other-bootclasspath-fragment",
135			contents: ["foo", "bar"],
136			fragments: [
137					{
138							apex: "com.android.art",
139							module: "art-bootclasspath-fragment",
140					},
141			],
142			hidden_api: {
143				split_packages: ["*"],
144			},
145		}
146`,
147	)
148
149	checkAPIScopeStubs := func(message string, info java.HiddenAPIInfo, apiScope *java.HiddenAPIScope, expectedPaths ...string) {
150		t.Helper()
151		paths := info.TransitiveStubDexJarsByScope.StubDexJarsForScope(apiScope)
152		android.AssertPathsRelativeToTopEquals(t, fmt.Sprintf("%s %s", message, apiScope), expectedPaths, paths)
153	}
154
155	// Check stub dex paths exported by art.
156	artFragment := result.Module("art-bootclasspath-fragment", "android_common")
157	artInfo, _ := android.OtherModuleProvider(result, artFragment, java.HiddenAPIInfoProvider)
158
159	bazPublicStubs := "out/soong/.intermediates/baz.stubs.exportable/android_common/dex/baz.stubs.exportable.jar"
160	bazSystemStubs := "out/soong/.intermediates/baz.stubs.exportable.system/android_common/dex/baz.stubs.exportable.system.jar"
161	bazTestStubs := "out/soong/.intermediates/baz.stubs.exportable.test/android_common/dex/baz.stubs.exportable.test.jar"
162
163	checkAPIScopeStubs("art", artInfo, java.PublicHiddenAPIScope, bazPublicStubs)
164	checkAPIScopeStubs("art", artInfo, java.SystemHiddenAPIScope, bazSystemStubs)
165	checkAPIScopeStubs("art", artInfo, java.TestHiddenAPIScope, bazTestStubs)
166	checkAPIScopeStubs("art", artInfo, java.CorePlatformHiddenAPIScope)
167
168	// Check stub dex paths exported by other.
169	otherFragment := result.Module("other-bootclasspath-fragment", "android_common")
170	otherInfo, _ := android.OtherModuleProvider(result, otherFragment, java.HiddenAPIInfoProvider)
171
172	fooPublicStubs := "out/soong/.intermediates/foo.stubs.exportable/android_common/dex/foo.stubs.exportable.jar"
173	fooSystemStubs := "out/soong/.intermediates/foo.stubs.exportable.system/android_common/dex/foo.stubs.exportable.system.jar"
174
175	checkAPIScopeStubs("other", otherInfo, java.PublicHiddenAPIScope, bazPublicStubs, fooPublicStubs)
176	checkAPIScopeStubs("other", otherInfo, java.SystemHiddenAPIScope, bazSystemStubs, fooSystemStubs)
177	checkAPIScopeStubs("other", otherInfo, java.TestHiddenAPIScope, bazTestStubs, fooSystemStubs)
178	checkAPIScopeStubs("other", otherInfo, java.CorePlatformHiddenAPIScope)
179}
180
181func TestBootclasspathFragmentInArtApex(t *testing.T) {
182	t.Parallel()
183	commonPreparer := android.GroupFixturePreparers(
184		prepareForTestWithBootclasspathFragment,
185		prepareForTestWithArtApex,
186
187		android.FixtureWithRootAndroidBp(`
188		apex {
189			name: "com.android.art",
190			key: "com.android.art.key",
191			bootclasspath_fragments: [
192				"art-bootclasspath-fragment",
193			],
194			// bar (like foo) should be transitively included in this apex because it is part of the
195			// art-bootclasspath-fragment bootclasspath_fragment.
196			updatable: false,
197		}
198
199		override_apex {
200			name: "com.mycompany.android.art",
201			base: "com.android.art",
202			min_sdk_version: "33", // mycompany overrides the min_sdk_version
203		}
204
205		apex_key {
206			name: "com.android.art.key",
207			public_key: "testkey.avbpubkey",
208			private_key: "testkey.pem",
209		}
210	`),
211	)
212
213	contentsInsert := func(contents []string) string {
214		insert := ""
215		if contents != nil {
216			insert = fmt.Sprintf(`contents: ["%s"],`, strings.Join(contents, `", "`))
217		}
218		return insert
219	}
220
221	addSource := func(contents ...string) android.FixturePreparer {
222		text := fmt.Sprintf(`
223			bootclasspath_fragment {
224				name: "art-bootclasspath-fragment",
225				image_name: "art",
226				%s
227				apex_available: [
228					"com.android.art",
229				],
230				hidden_api: {
231					split_packages: ["*"],
232				},
233			}
234		`, contentsInsert(contents))
235
236		for _, content := range contents {
237			text += fmt.Sprintf(`
238				java_library {
239					name: "%[1]s",
240					srcs: ["%[1]s.java"],
241					installable: true,
242					apex_available: [
243						"com.android.art",
244					],
245					min_sdk_version: "33",
246				}
247			`, content)
248		}
249
250		return android.FixtureAddTextFile("art/build/boot/Android.bp", text)
251	}
252
253	addPrebuilt := func(prefer bool, contents ...string) android.FixturePreparer {
254		text := fmt.Sprintf(`
255			prebuilt_apex {
256				name: "com.android.art",
257				arch: {
258					arm64: {
259						src: "com.android.art-arm64.apex",
260					},
261					arm: {
262						src: "com.android.art-arm.apex",
263					},
264				},
265				exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
266			}
267
268			prebuilt_bootclasspath_fragment {
269				name: "art-bootclasspath-fragment",
270				image_name: "art",
271				%s
272				prefer: %t,
273				apex_available: [
274					"com.android.art",
275				],
276				hidden_api: {
277					annotation_flags: "hiddenapi/annotation-flags.csv",
278					metadata: "hiddenapi/metadata.csv",
279					index: "hiddenapi/index.csv",
280					stub_flags: "hiddenapi/stub-flags.csv",
281					all_flags: "hiddenapi/all-flags.csv",
282				},
283			}
284		`, contentsInsert(contents), prefer)
285
286		for _, content := range contents {
287			text += fmt.Sprintf(`
288				java_import {
289					name: "%[1]s",
290					prefer: %[2]t,
291					jars: ["%[1]s.jar"],
292					apex_available: [
293						"com.android.art",
294					],
295					min_sdk_version: "33",
296					compile_dex: true,
297				}
298			`, content, prefer)
299		}
300
301		return android.FixtureAddTextFile("prebuilts/module_sdk/art/Android.bp", text)
302	}
303
304	t.Run("boot image files from source", func(t *testing.T) {
305		t.Parallel()
306		result := android.GroupFixturePreparers(
307			commonPreparer,
308
309			// Configure some libraries in the art bootclasspath_fragment that match the source
310			// bootclasspath_fragment's contents property.
311			java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
312			dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:foo", "com.android.art:bar"),
313			addSource("foo", "bar"),
314			java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
315		).RunTest(t)
316
317		ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
318			"etc/boot-image.prof",
319			"etc/classpaths/bootclasspath.pb",
320			"javalib/bar.jar",
321			"javalib/foo.jar",
322		})
323
324		java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
325			`all_apex_contributions`,
326			`art-bootclasspath-fragment`,
327			`com.android.art.key`,
328			`dex2oatd`,
329		})
330
331		// Make sure that the source bootclasspath_fragment copies its dex files to the predefined
332		// locations for the art image.
333		module := result.ModuleForTests(t, "dex_bootjars", "android_common")
334		checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
335	})
336
337	t.Run("boot image files from source of override apex", func(t *testing.T) {
338		t.Parallel()
339		result := android.GroupFixturePreparers(
340			commonPreparer,
341
342			// Configure some libraries in the art bootclasspath_fragment that match the source
343			// bootclasspath_fragment's contents property.
344			java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
345			dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:foo", "com.android.art:bar"),
346			addSource("foo", "bar"),
347			java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
348		).RunTest(t)
349
350		ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.mycompany.android.art_com.mycompany.android.art", []string{
351			"etc/boot-image.prof",
352			"etc/classpaths/bootclasspath.pb",
353			"javalib/bar.jar",
354			"javalib/foo.jar",
355		})
356	})
357
358	t.Run("generate boot image profile even if dexpreopt is disabled", func(t *testing.T) {
359		t.Parallel()
360		result := android.GroupFixturePreparers(
361			commonPreparer,
362
363			// Configure some libraries in the art bootclasspath_fragment that match the source
364			// bootclasspath_fragment's contents property.
365			java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
366			addSource("foo", "bar"),
367			java.FixtureSetBootImageInstallDirOnDevice("art", "system/framework"),
368			dexpreopt.FixtureDisableDexpreoptBootImages(true),
369		).RunTest(t)
370
371		ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
372			"etc/boot-image.prof",
373			"etc/classpaths/bootclasspath.pb",
374			"javalib/bar.jar",
375			"javalib/foo.jar",
376		})
377	})
378
379	t.Run("boot image disable generate profile", func(t *testing.T) {
380		t.Parallel()
381		result := android.GroupFixturePreparers(
382			commonPreparer,
383
384			// Configure some libraries in the art bootclasspath_fragment that match the source
385			// bootclasspath_fragment's contents property.
386			java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
387			addSource("foo", "bar"),
388			dexpreopt.FixtureDisableGenerateProfile(true),
389		).RunTest(t)
390
391		files := getFiles(t, result.TestContext, "com.android.art", "android_common_com.android.art")
392		for _, file := range files {
393			matched, _ := path.Match("etc/boot-image.prof", file.path)
394			android.AssertBoolEquals(t, "\"etc/boot-image.prof\" should not be in the APEX", matched, false)
395		}
396	})
397
398	t.Run("boot image files with preferred prebuilt", func(t *testing.T) {
399		t.Parallel()
400		result := android.GroupFixturePreparers(
401			commonPreparer,
402
403			// Configure some libraries in the art bootclasspath_fragment that match the source
404			// bootclasspath_fragment's contents property.
405			java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
406			dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:foo", "com.android.art:bar"),
407			addSource("foo", "bar"),
408
409			// Make sure that a preferred prebuilt with consistent contents doesn't affect the apex.
410			addPrebuilt(true, "foo", "bar"),
411			android.FixtureMergeMockFs(android.MockFS{
412				"apex_contributions/Android.bp": []byte(`
413				apex_contributions {
414					name: "prebuilt_art_contributions",
415					contents: ["prebuilt_com.android.art"],
416					api_domain: "com.android.art",
417				}
418			`)}),
419			android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "prebuilt_art_contributions"),
420
421			java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
422		).RunTest(t)
423
424		ensureExactDeapexedContents(t, result.TestContext, "prebuilt_com.android.art", "android_common_prebuilt_com.android.art", []string{
425			"etc/boot-image.prof",
426			"javalib/bar.jar",
427			"javalib/foo.jar",
428		})
429
430		java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
431			`all_apex_contributions`,
432			`art-bootclasspath-fragment`,
433			`com.android.art.key`,
434			`dex2oatd`,
435			`prebuilt_art-bootclasspath-fragment`,
436			`prebuilt_com.android.art`,
437		})
438
439		// Make sure that the prebuilt bootclasspath_fragment copies its dex files to the predefined
440		// locations for the art image.
441		module := result.ModuleForTests(t, "dex_bootjars", "android_common")
442		checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
443	})
444
445	t.Run("source with inconsistency between config and contents", func(t *testing.T) {
446		t.Parallel()
447		android.GroupFixturePreparers(
448			commonPreparer,
449
450			// Create an inconsistency between the ArtApexJars configuration and the art source
451			// bootclasspath_fragment module's contents property.
452			java.FixtureConfigureBootJars("com.android.art:foo"),
453			addSource("foo", "bar"),
454		).
455			ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`\QArtApexJars configuration specifies []string{"foo"}, contents property specifies []string{"foo", "bar"}\E`)).
456			RunTest(t)
457	})
458
459	t.Run("prebuilt with inconsistency between config and contents", func(t *testing.T) {
460		t.Parallel()
461		android.GroupFixturePreparers(
462			commonPreparer,
463
464			// Create an inconsistency between the ArtApexJars configuration and the art
465			// prebuilt_bootclasspath_fragment module's contents property.
466			java.FixtureConfigureBootJars("com.android.art:foo"),
467			addPrebuilt(false, "foo", "bar"),
468		).
469			ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`\QArtApexJars configuration specifies []string{"foo"}, contents property specifies []string{"foo", "bar"}\E`)).
470			RunTest(t)
471	})
472
473	t.Run("preferred prebuilt with inconsistency between config and contents", func(t *testing.T) {
474		t.Parallel()
475		android.GroupFixturePreparers(
476			commonPreparer,
477
478			// Create an inconsistency between the ArtApexJars configuration and the art
479			// prebuilt_bootclasspath_fragment module's contents property.
480			java.FixtureConfigureBootJars("com.android.art:foo"),
481			addPrebuilt(true, "foo", "bar"),
482
483			// Source contents property is consistent with the config.
484			addSource("foo"),
485		).
486			ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`\QArtApexJars configuration specifies []string{"foo"}, contents property specifies []string{"foo", "bar"}\E`)).
487			RunTest(t)
488	})
489
490	t.Run("source preferred and prebuilt with inconsistency between config and contents", func(t *testing.T) {
491		t.Parallel()
492		android.GroupFixturePreparers(
493			commonPreparer,
494
495			// Create an inconsistency between the ArtApexJars configuration and the art
496			// prebuilt_bootclasspath_fragment module's contents property.
497			java.FixtureConfigureBootJars("com.android.art:foo"),
498			addPrebuilt(false, "foo", "bar"),
499
500			// Source contents property is consistent with the config.
501			addSource("foo"),
502
503			// This should pass because while the prebuilt is inconsistent with the configuration it is
504			// not actually used.
505		).RunTest(t)
506	})
507}
508
509func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
510	t.Parallel()
511	preparers := android.GroupFixturePreparers(
512		prepareForTestWithBootclasspathFragment,
513		prepareForTestWithArtApex,
514
515		android.FixtureMergeMockFs(android.MockFS{
516			"com.android.art-arm64.apex": nil,
517			"com.android.art-arm.apex":   nil,
518		}),
519
520		// Configure some libraries in the art bootclasspath_fragment.
521		java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
522		dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:foo", "com.android.art:bar"),
523		java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
524		android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "prebuilt_art_contributions"),
525	)
526
527	bp := `
528		prebuilt_apex {
529			name: "com.android.art",
530			arch: {
531				arm64: {
532					src: "com.android.art-arm64.apex",
533				},
534				arm: {
535					src: "com.android.art-arm.apex",
536				},
537			},
538			exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
539		}
540
541		java_import {
542			name: "foo",
543			jars: ["foo.jar"],
544			apex_available: [
545				"com.android.art",
546			],
547		}
548
549		java_import {
550			name: "bar",
551			jars: ["bar.jar"],
552			apex_available: [
553				"com.android.art",
554			],
555		}
556
557		prebuilt_bootclasspath_fragment {
558			name: "art-bootclasspath-fragment",
559			image_name: "art",
560			// Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
561			contents: ["foo", "bar"],
562			apex_available: [
563				"com.android.art",
564			],
565			hidden_api: {
566				annotation_flags: "hiddenapi/annotation-flags.csv",
567				metadata: "hiddenapi/metadata.csv",
568				index: "hiddenapi/index.csv",
569				stub_flags: "hiddenapi/stub-flags.csv",
570				all_flags: "hiddenapi/all-flags.csv",
571			},
572		}
573
574		// A prebuilt apex with the same apex_name that shouldn't interfere when it isn't enabled.
575		prebuilt_apex {
576			name: "com.mycompany.android.art",
577			apex_name: "com.android.art",
578			%s
579			src: "com.mycompany.android.art.apex",
580			exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
581		}
582
583		apex_contributions {
584			name: "prebuilt_art_contributions",
585			contents: ["prebuilt_com.android.art"],
586			api_domain: "com.android.art",
587		}
588	`
589
590	t.Run("disabled alternative APEX", func(t *testing.T) {
591		t.Parallel()
592		result := preparers.RunTestWithBp(t, fmt.Sprintf(bp, "enabled: false,"))
593
594		java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_prebuilt_com.android.art", []string{
595			`all_apex_contributions`,
596			`dex2oatd`,
597			`prebuilt_art-bootclasspath-fragment`,
598		})
599
600		java.CheckModuleDependencies(t, result.TestContext, "art-bootclasspath-fragment", "android_common_prebuilt_com.android.art", []string{
601			`all_apex_contributions`,
602			`dex2oatd`,
603			`prebuilt_bar`,
604			`prebuilt_foo`,
605		})
606
607		module := result.ModuleForTests(t, "dex_bootjars", "android_common")
608		checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
609	})
610}
611
612// checkCopiesToPredefinedLocationForArt checks that the supplied modules are copied to the
613// predefined locations of boot dex jars used as inputs for the ART boot image.
614func checkCopiesToPredefinedLocationForArt(t *testing.T, config android.Config, module android.TestingModule, modules ...string) {
615	t.Helper()
616	bootJarLocations := []string{}
617	for _, output := range module.AllOutputs() {
618		output = android.StringRelativeToTop(config, output)
619		if strings.HasPrefix(output, "out/soong/dexpreopt_arm64/dex_artjars_input/") {
620			bootJarLocations = append(bootJarLocations, output)
621		}
622	}
623
624	sort.Strings(bootJarLocations)
625	expected := []string{}
626	for _, m := range modules {
627		expected = append(expected, fmt.Sprintf("out/soong/dexpreopt_arm64/dex_artjars_input/%s.jar", m))
628	}
629	sort.Strings(expected)
630
631	android.AssertArrayString(t, "copies to predefined locations for art", expected, bootJarLocations)
632}
633
634func TestBootclasspathFragmentContentsNoName(t *testing.T) {
635	t.Parallel()
636	result := android.GroupFixturePreparers(
637		prepareForTestWithBootclasspathFragment,
638		prepareForTestWithMyapex,
639		// Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
640		java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
641		// Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
642		// is disabled.
643		android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
644
645		java.PrepareForTestWithJavaSdkLibraryFiles,
646		java.FixtureWithLastReleaseApis("foo"),
647	).RunTestWithBp(t, `
648		apex {
649			name: "myapex",
650			key: "myapex.key",
651			bootclasspath_fragments: [
652				"mybootclasspathfragment",
653			],
654			updatable: false,
655		}
656
657		apex_key {
658			name: "myapex.key",
659			public_key: "testkey.avbpubkey",
660			private_key: "testkey.pem",
661		}
662
663		java_sdk_library {
664			name: "foo",
665			srcs: ["b.java"],
666			shared_library: false,
667			public: {enabled: true},
668			apex_available: [
669				"myapex",
670			],
671		}
672
673		java_library {
674			name: "bar",
675			srcs: ["b.java"],
676			installable: true,
677			apex_available: [
678				"myapex",
679			],
680		}
681
682		bootclasspath_fragment {
683			name: "mybootclasspathfragment",
684			contents: [
685				"foo",
686				"bar",
687			],
688			apex_available: [
689				"myapex",
690			],
691			hidden_api: {
692				split_packages: ["*"],
693			},
694		}
695	`)
696
697	ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex", []string{
698		// This does not include art, oat or vdex files as they are only included for the art boot
699		// image.
700		"etc/classpaths/bootclasspath.pb",
701		"javalib/bar.jar",
702		"javalib/foo.jar",
703	})
704
705	java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{
706		`all_apex_contributions`,
707		`dex2oatd`,
708		`myapex.key`,
709		`mybootclasspathfragment`,
710	})
711
712	apex := result.ModuleForTests(t, "myapex", "android_common_myapex")
713	apexRule := apex.Rule("apexRule")
714	copyCommands := apexRule.Args["copy_commands"]
715
716	// Make sure that the fragment provides the hidden API encoded dex jars to the APEX.
717	fragment := result.Module("mybootclasspathfragment", "android_common_myapex")
718
719	info, _ := android.OtherModuleProvider(result, fragment, java.BootclasspathFragmentApexContentInfoProvider)
720
721	checkFragmentExportedDexJar := func(name string, expectedDexJar string) {
722		module := result.Module(name, "android_common_apex10000")
723		dexJar, err := info.DexBootJarPathForContentModule(module)
724		if err != nil {
725			t.Error(err)
726		}
727		android.AssertPathRelativeToTopEquals(t, name+" dex", expectedDexJar, dexJar)
728
729		expectedCopyCommand := fmt.Sprintf("&& cp -f %s out/soong/.intermediates/myapex/android_common_myapex/image.apex/javalib/%s.jar", expectedDexJar, name)
730		android.AssertStringDoesContain(t, name+" apex copy command", copyCommands, expectedCopyCommand)
731	}
732
733	checkFragmentExportedDexJar("foo", "out/soong/.intermediates/mybootclasspathfragment/android_common_myapex/hiddenapi-modular/encoded/foo.jar")
734	checkFragmentExportedDexJar("bar", "out/soong/.intermediates/mybootclasspathfragment/android_common_myapex/hiddenapi-modular/encoded/bar.jar")
735}
736
737func getDexJarPath(result *android.TestResult, name string) string {
738	module := result.Module(name, "android_common")
739	return module.(java.UsesLibraryDependency).DexJarBuildPath(moduleErrorfTestCtx{}).Path().RelativeToTop().String()
740}
741
742// TestBootclasspathFragment_HiddenAPIList checks to make sure that the correct parameters are
743// passed to the hiddenapi list tool.
744func TestBootclasspathFragment_HiddenAPIList(t *testing.T) {
745	t.Parallel()
746	result := android.GroupFixturePreparers(
747		prepareForTestWithBootclasspathFragment,
748		prepareForTestWithArtApex,
749		prepareForTestWithMyapex,
750		// Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
751		java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
752		java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
753		// Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
754		// is disabled.
755		android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
756
757		java.PrepareForTestWithJavaSdkLibraryFiles,
758		java.FixtureWithLastReleaseApis("foo", "quuz"),
759		android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"),
760	).RunTestWithBp(t, `
761		apex {
762			name: "com.android.art",
763			key: "com.android.art.key",
764			bootclasspath_fragments: ["art-bootclasspath-fragment"],
765			updatable: false,
766		}
767
768		apex_key {
769			name: "com.android.art.key",
770			public_key: "com.android.art.avbpubkey",
771			private_key: "com.android.art.pem",
772		}
773
774		java_library {
775			name: "baz",
776			apex_available: [
777				"com.android.art",
778			],
779			srcs: ["b.java"],
780			compile_dex: true,
781			sdk_version: "core_current",
782		}
783
784		java_sdk_library {
785			name: "quuz",
786			apex_available: [
787				"com.android.art",
788			],
789			srcs: ["b.java"],
790			compile_dex: true,
791			public: {enabled: true},
792			system: {enabled: true},
793			test: {enabled: true},
794			module_lib: {enabled: true},
795		}
796
797		bootclasspath_fragment {
798			name: "art-bootclasspath-fragment",
799			image_name: "art",
800			// Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
801			contents: ["baz", "quuz"],
802			apex_available: [
803				"com.android.art",
804			],
805			hidden_api: {
806				split_packages: ["*"],
807			},
808		}
809
810		apex {
811			name: "myapex",
812			key: "myapex.key",
813			bootclasspath_fragments: [
814				"mybootclasspathfragment",
815			],
816			updatable: false,
817		}
818
819		apex_key {
820			name: "myapex.key",
821			public_key: "testkey.avbpubkey",
822			private_key: "testkey.pem",
823		}
824
825		java_sdk_library {
826			name: "foo",
827			srcs: ["b.java"],
828			shared_library: false,
829			public: {enabled: true},
830			apex_available: [
831				"myapex",
832			],
833		}
834
835		java_library {
836			name: "bar",
837			srcs: ["b.java"],
838			installable: true,
839			apex_available: [
840				"myapex",
841			],
842		}
843
844		bootclasspath_fragment {
845			name: "mybootclasspathfragment",
846			contents: [
847				"foo",
848				"bar",
849			],
850			apex_available: [
851				"myapex",
852			],
853			fragments: [
854				{
855					apex: "com.android.art",
856					module: "art-bootclasspath-fragment",
857				},
858			],
859			hidden_api: {
860				split_packages: ["*"],
861			},
862		}
863	`)
864
865	java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_myapex", []string{
866		"all_apex_contributions",
867		"bar",
868		"com.android.art",
869		"dex2oatd",
870		"foo",
871	})
872
873	fooStubs := getDexJarPath(result, "foo.stubs.exportable")
874	quuzPublicStubs := getDexJarPath(result, "quuz.stubs.exportable")
875	quuzSystemStubs := getDexJarPath(result, "quuz.stubs.exportable.system")
876	quuzTestStubs := getDexJarPath(result, "quuz.stubs.exportable.test")
877	quuzModuleLibStubs := getDexJarPath(result, "quuz.stubs.exportable.module_lib")
878
879	// Make sure that the fragment uses the quuz stub dex jars when generating the hidden API flags.
880	fragment := result.ModuleForTests(t, "mybootclasspathfragment", "android_common_myapex")
881
882	rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
883	command := rule.RuleParams.Command
884	android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
885
886	// Make sure that the quuz stubs are available for resolving references from the implementation
887	// boot dex jars provided by this module.
888	android.AssertStringDoesContain(t, "quuz widest", command, "--dependency-stub-dex="+quuzModuleLibStubs)
889
890	// Make sure that the quuz stubs are available for resolving references from the different API
891	// stubs provided by this module.
892	android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+quuzPublicStubs+":"+fooStubs)
893	android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+quuzSystemStubs+":"+fooStubs)
894	android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+quuzTestStubs+":"+fooStubs)
895}
896
897// TestBootclasspathFragment_AndroidNonUpdatable checks to make sure that setting
898// additional_stubs: ["android-non-updatable"] causes the source android-non-updatable modules to be
899// added to the hiddenapi list tool.
900func TestBootclasspathFragment_AndroidNonUpdatable_FromSource(t *testing.T) {
901	t.Parallel()
902	result := android.GroupFixturePreparers(
903		prepareForTestWithBootclasspathFragment,
904		prepareForTestWithArtApex,
905		prepareForTestWithMyapex,
906		// Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
907		java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
908		java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
909		// Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
910		// is disabled.
911		android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
912		android.FixtureModifyConfig(func(config android.Config) {
913			config.SetBuildFromTextStub(false)
914		}),
915
916		java.PrepareForTestWithJavaSdkLibraryFiles,
917		java.FixtureWithLastReleaseApis("foo", "android-non-updatable"),
918	).RunTestWithBp(t, `
919		java_sdk_library {
920			name: "android-non-updatable",
921			srcs: ["b.java"],
922			compile_dex: true,
923			public: {
924				enabled: true,
925			},
926			system: {
927				enabled: true,
928			},
929			test: {
930				enabled: true,
931			},
932			module_lib: {
933				enabled: true,
934			},
935		}
936
937		apex {
938			name: "com.android.art",
939			key: "com.android.art.key",
940			bootclasspath_fragments: ["art-bootclasspath-fragment"],
941			updatable: false,
942		}
943
944		apex_key {
945			name: "com.android.art.key",
946			public_key: "com.android.art.avbpubkey",
947			private_key: "com.android.art.pem",
948		}
949
950		java_library {
951			name: "baz",
952			apex_available: [
953				"com.android.art",
954			],
955			srcs: ["b.java"],
956			compile_dex: true,
957			sdk_version: "core_current",
958		}
959
960		java_library {
961			name: "quuz",
962			apex_available: [
963				"com.android.art",
964			],
965			srcs: ["b.java"],
966			compile_dex: true,
967		}
968
969		bootclasspath_fragment {
970			name: "art-bootclasspath-fragment",
971			image_name: "art",
972			// Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
973			contents: ["baz", "quuz"],
974			apex_available: [
975				"com.android.art",
976			],
977			hidden_api: {
978				split_packages: ["*"],
979			},
980		}
981
982		apex {
983			name: "myapex",
984			key: "myapex.key",
985			bootclasspath_fragments: [
986				"mybootclasspathfragment",
987			],
988			updatable: false,
989		}
990
991		apex_key {
992			name: "myapex.key",
993			public_key: "testkey.avbpubkey",
994			private_key: "testkey.pem",
995		}
996
997		java_sdk_library {
998			name: "foo",
999			srcs: ["b.java"],
1000			shared_library: false,
1001			public: {enabled: true},
1002			apex_available: [
1003				"myapex",
1004			],
1005		}
1006
1007		java_library {
1008			name: "bar",
1009			srcs: ["b.java"],
1010			installable: true,
1011			apex_available: [
1012				"myapex",
1013			],
1014		}
1015
1016		bootclasspath_fragment {
1017			name: "mybootclasspathfragment",
1018			contents: [
1019				"foo",
1020				"bar",
1021			],
1022			apex_available: [
1023				"myapex",
1024			],
1025			additional_stubs: ["android-non-updatable"],
1026			fragments: [
1027				{
1028					apex: "com.android.art",
1029					module: "art-bootclasspath-fragment",
1030				},
1031			],
1032			hidden_api: {
1033				split_packages: ["*"],
1034			},
1035		}
1036	`)
1037
1038	java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_myapex", []string{
1039		"all_apex_contributions",
1040		"android-non-updatable.stubs",
1041		"android-non-updatable.stubs.module_lib",
1042		"android-non-updatable.stubs.system",
1043		"android-non-updatable.stubs.test",
1044		"bar",
1045		"com.android.art",
1046		"dex2oatd",
1047		"foo",
1048	})
1049
1050	nonUpdatablePublicStubs := getDexJarPath(result, "android-non-updatable.stubs")
1051	nonUpdatableSystemStubs := getDexJarPath(result, "android-non-updatable.stubs.system")
1052	nonUpdatableTestStubs := getDexJarPath(result, "android-non-updatable.stubs.test")
1053	nonUpdatableModuleLibStubs := getDexJarPath(result, "android-non-updatable.stubs.module_lib")
1054
1055	// Make sure that the fragment uses the android-non-updatable modules when generating the hidden
1056	// API flags.
1057	fragment := result.ModuleForTests(t, "mybootclasspathfragment", "android_common_myapex")
1058
1059	rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
1060	command := rule.RuleParams.Command
1061	android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
1062
1063	// Make sure that the module_lib non-updatable stubs are available for resolving references from
1064	// the implementation boot dex jars provided by this module.
1065	android.AssertStringDoesContain(t, "android-non-updatable widest", command, "--dependency-stub-dex="+nonUpdatableModuleLibStubs)
1066
1067	// Make sure that the appropriate non-updatable stubs are available for resolving references from
1068	// the different API stubs provided by this module.
1069	android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+nonUpdatablePublicStubs)
1070	android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+nonUpdatableSystemStubs)
1071	android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+nonUpdatableTestStubs)
1072}
1073
1074func TestBootclasspathFragment_AndroidNonUpdatable_FromText(t *testing.T) {
1075	t.Parallel()
1076	result := android.GroupFixturePreparers(
1077		prepareForTestWithBootclasspathFragment,
1078		prepareForTestWithArtApex,
1079		prepareForTestWithMyapex,
1080		// Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
1081		java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
1082		java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
1083		// Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
1084		// is disabled.
1085		android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
1086		android.FixtureModifyConfig(func(config android.Config) {
1087			config.SetBuildFromTextStub(true)
1088		}),
1089
1090		java.PrepareForTestWithJavaSdkLibraryFiles,
1091		java.FixtureWithLastReleaseApis("foo", "android-non-updatable"),
1092	).RunTestWithBp(t, `
1093		java_sdk_library {
1094			name: "android-non-updatable",
1095			srcs: ["b.java"],
1096			compile_dex: true,
1097			public: {
1098				enabled: true,
1099			},
1100			system: {
1101				enabled: true,
1102			},
1103			test: {
1104				enabled: true,
1105			},
1106			module_lib: {
1107				enabled: true,
1108			},
1109		}
1110
1111		apex {
1112			name: "com.android.art",
1113			key: "com.android.art.key",
1114			bootclasspath_fragments: ["art-bootclasspath-fragment"],
1115			updatable: false,
1116		}
1117
1118		apex_key {
1119			name: "com.android.art.key",
1120			public_key: "com.android.art.avbpubkey",
1121			private_key: "com.android.art.pem",
1122		}
1123
1124		java_library {
1125			name: "baz",
1126			apex_available: [
1127				"com.android.art",
1128			],
1129			srcs: ["b.java"],
1130			compile_dex: true,
1131			sdk_version: "core_current",
1132		}
1133
1134		java_library {
1135			name: "quuz",
1136			apex_available: [
1137				"com.android.art",
1138			],
1139			srcs: ["b.java"],
1140			compile_dex: true,
1141		}
1142
1143		bootclasspath_fragment {
1144			name: "art-bootclasspath-fragment",
1145			image_name: "art",
1146			// Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
1147			contents: ["baz", "quuz"],
1148			apex_available: [
1149				"com.android.art",
1150			],
1151			hidden_api: {
1152				split_packages: ["*"],
1153			},
1154		}
1155
1156		apex {
1157			name: "myapex",
1158			key: "myapex.key",
1159			bootclasspath_fragments: [
1160				"mybootclasspathfragment",
1161			],
1162			updatable: false,
1163		}
1164
1165		apex_key {
1166			name: "myapex.key",
1167			public_key: "testkey.avbpubkey",
1168			private_key: "testkey.pem",
1169		}
1170
1171		java_sdk_library {
1172			name: "foo",
1173			srcs: ["b.java"],
1174			shared_library: false,
1175			public: {enabled: true},
1176			apex_available: [
1177				"myapex",
1178			],
1179		}
1180
1181		java_library {
1182			name: "bar",
1183			srcs: ["b.java"],
1184			installable: true,
1185			apex_available: [
1186				"myapex",
1187			],
1188		}
1189
1190		bootclasspath_fragment {
1191			name: "mybootclasspathfragment",
1192			contents: [
1193				"foo",
1194				"bar",
1195			],
1196			apex_available: [
1197				"myapex",
1198			],
1199			additional_stubs: ["android-non-updatable"],
1200			fragments: [
1201				{
1202					apex: "com.android.art",
1203					module: "art-bootclasspath-fragment",
1204				},
1205			],
1206			hidden_api: {
1207				split_packages: ["*"],
1208			},
1209		}
1210	`)
1211
1212	java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_myapex", []string{
1213		"all_apex_contributions",
1214		"android-non-updatable.stubs",
1215		"android-non-updatable.stubs.system",
1216		"android-non-updatable.stubs.test",
1217		"android-non-updatable.stubs.test_module_lib",
1218		"bar",
1219		"com.android.art",
1220		"dex2oatd",
1221		"foo",
1222	})
1223
1224	nonUpdatableTestModuleLibStubs := getDexJarPath(result, "android-non-updatable.stubs.test_module_lib")
1225
1226	// Make sure that the fragment uses the android-non-updatable modules when generating the hidden
1227	// API flags.
1228	fragment := result.ModuleForTests(t, "mybootclasspathfragment", "android_common_myapex")
1229
1230	rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
1231	command := rule.RuleParams.Command
1232	android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
1233
1234	// Make sure that the test_module_lib non-updatable stubs are available for resolving references from
1235	// the implementation boot dex jars provided by this module.
1236	android.AssertStringDoesContain(t, "android-non-updatable widest", command, "--dependency-stub-dex="+nonUpdatableTestModuleLibStubs)
1237}
1238
1239// TestBootclasspathFragment_AndroidNonUpdatable_AlwaysUsePrebuiltSdks checks to make sure that
1240// setting additional_stubs: ["android-non-updatable"] causes the prebuilt android-non-updatable
1241// modules to be added to the hiddenapi list tool.
1242func TestBootclasspathFragment_AndroidNonUpdatable_AlwaysUsePrebuiltSdks(t *testing.T) {
1243	t.Parallel()
1244	result := android.GroupFixturePreparers(
1245		prepareForTestWithBootclasspathFragment,
1246		java.PrepareForTestWithDexpreopt,
1247		prepareForTestWithArtApex,
1248		prepareForTestWithMyapex,
1249		// Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
1250		java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
1251		java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
1252		// Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
1253		// is disabled.
1254		android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
1255
1256		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1257			variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
1258		}),
1259
1260		java.PrepareForTestWithJavaSdkLibraryFiles,
1261		java.FixtureWithPrebuiltApis(map[string][]string{
1262			"current": {"android-non-updatable"},
1263			"30":      {"foo"},
1264		}),
1265	).RunTestWithBp(t, `
1266		apex {
1267			name: "com.android.art",
1268			key: "com.android.art.key",
1269			bootclasspath_fragments: ["art-bootclasspath-fragment"],
1270			updatable: false,
1271		}
1272
1273		apex_key {
1274			name: "com.android.art.key",
1275			public_key: "com.android.art.avbpubkey",
1276			private_key: "com.android.art.pem",
1277		}
1278
1279		java_library {
1280			name: "baz",
1281			apex_available: [
1282				"com.android.art",
1283			],
1284			srcs: ["b.java"],
1285			compile_dex: true,
1286			sdk_version: "core_current",
1287		}
1288
1289		java_library {
1290			name: "quuz",
1291			apex_available: [
1292				"com.android.art",
1293			],
1294			srcs: ["b.java"],
1295			compile_dex: true,
1296		}
1297
1298		bootclasspath_fragment {
1299			name: "art-bootclasspath-fragment",
1300			image_name: "art",
1301			// Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
1302			contents: ["baz", "quuz"],
1303			apex_available: [
1304				"com.android.art",
1305			],
1306			hidden_api: {
1307				split_packages: ["*"],
1308			},
1309		}
1310
1311		apex {
1312			name: "myapex",
1313			key: "myapex.key",
1314			bootclasspath_fragments: [
1315				"mybootclasspathfragment",
1316			],
1317			updatable: false,
1318		}
1319
1320		apex_key {
1321			name: "myapex.key",
1322			public_key: "testkey.avbpubkey",
1323			private_key: "testkey.pem",
1324		}
1325
1326		java_sdk_library {
1327			name: "foo",
1328			srcs: ["b.java"],
1329			shared_library: false,
1330			public: {enabled: true},
1331			apex_available: [
1332				"myapex",
1333			],
1334		}
1335
1336		java_library {
1337			name: "bar",
1338			srcs: ["b.java"],
1339			installable: true,
1340			apex_available: [
1341				"myapex",
1342			],
1343		}
1344
1345		bootclasspath_fragment {
1346			name: "mybootclasspathfragment",
1347			contents: [
1348				"foo",
1349				"bar",
1350			],
1351			apex_available: [
1352				"myapex",
1353			],
1354			additional_stubs: ["android-non-updatable"],
1355			fragments: [
1356				{
1357					apex: "com.android.art",
1358					module: "art-bootclasspath-fragment",
1359				},
1360			],
1361			hidden_api: {
1362				split_packages: ["*"],
1363			},
1364		}
1365	`)
1366
1367	java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_myapex", []string{
1368		"all_apex_contributions",
1369		"bar",
1370		"com.android.art",
1371		"dex2oatd",
1372		"foo",
1373		"prebuilt_sdk_module-lib_current_android-non-updatable",
1374		"prebuilt_sdk_public_current_android-non-updatable",
1375		"prebuilt_sdk_system_current_android-non-updatable",
1376		"prebuilt_sdk_test_current_android-non-updatable",
1377	})
1378
1379	nonUpdatablePublicStubs := getDexJarPath(result, "sdk_public_current_android-non-updatable")
1380	nonUpdatableSystemStubs := getDexJarPath(result, "sdk_system_current_android-non-updatable")
1381	nonUpdatableTestStubs := getDexJarPath(result, "sdk_test_current_android-non-updatable")
1382	nonUpdatableModuleLibStubs := getDexJarPath(result, "sdk_module-lib_current_android-non-updatable")
1383
1384	// Make sure that the fragment uses the android-non-updatable modules when generating the hidden
1385	// API flags.
1386	fragment := result.ModuleForTests(t, "mybootclasspathfragment", "android_common_myapex")
1387
1388	rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
1389	command := rule.RuleParams.Command
1390	android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
1391
1392	// Make sure that the module_lib non-updatable stubs are available for resolving references from
1393	// the implementation boot dex jars provided by this module.
1394	android.AssertStringDoesContain(t, "android-non-updatable widest", command, "--dependency-stub-dex="+nonUpdatableModuleLibStubs)
1395
1396	// Make sure that the appropriate non-updatable stubs are available for resolving references from
1397	// the different API stubs provided by this module.
1398	android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+nonUpdatablePublicStubs)
1399	android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+nonUpdatableSystemStubs)
1400	android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+nonUpdatableTestStubs)
1401}
1402
1403func TestBootclasspathFragmentProtoContainsMinSdkVersion(t *testing.T) {
1404	t.Parallel()
1405	result := android.GroupFixturePreparers(
1406		prepareForTestWithBootclasspathFragment,
1407		prepareForTestWithMyapex,
1408		// Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
1409		java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
1410		// Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
1411		// is disabled.
1412		android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
1413
1414		java.PrepareForTestWithJavaSdkLibraryFiles,
1415		java.FixtureWithLastReleaseApis("foo", "bar"),
1416	).RunTestWithBp(t, `
1417		apex {
1418			name: "myapex",
1419			key: "myapex.key",
1420			bootclasspath_fragments: [
1421				"mybootclasspathfragment",
1422			],
1423			updatable: false,
1424		}
1425
1426		apex_key {
1427			name: "myapex.key",
1428			public_key: "testkey.avbpubkey",
1429			private_key: "testkey.pem",
1430		}
1431
1432		java_sdk_library {
1433			name: "foo",
1434			srcs: ["b.java"],
1435			shared_library: false,
1436			public: {enabled: true},
1437			apex_available: [
1438				"myapex",
1439			],
1440			min_sdk_version: "33",
1441		}
1442
1443		java_sdk_library {
1444			name: "bar",
1445			srcs: ["b.java"],
1446			shared_library: false,
1447			public: {enabled: true},
1448			apex_available: [
1449				"myapex",
1450			],
1451			min_sdk_version: "34",
1452		}
1453
1454		bootclasspath_fragment {
1455			name: "mybootclasspathfragment",
1456			contents: [
1457				"foo",
1458				"bar",
1459			],
1460			apex_available: [
1461				"myapex",
1462			],
1463			hidden_api: {
1464				split_packages: ["*"],
1465			},
1466		}
1467	`)
1468
1469	fragment := result.ModuleForTests(t, "mybootclasspathfragment", "android_common_myapex")
1470	classPathProtoContent := android.ContentFromFileRuleForTests(t, result.TestContext, fragment.Output("bootclasspath.pb.textproto"))
1471	// foo
1472	ensureContains(t, classPathProtoContent, `jars {
1473path: "/apex/myapex/javalib/foo.jar"
1474classpath: BOOTCLASSPATH
1475min_sdk_version: "33"
1476max_sdk_version: ""
1477}
1478`)
1479	// bar
1480	ensureContains(t, classPathProtoContent, `jars {
1481path: "/apex/myapex/javalib/bar.jar"
1482classpath: BOOTCLASSPATH
1483min_sdk_version: "34"
1484max_sdk_version: ""
1485}
1486`)
1487}
1488
1489// TODO(b/177892522) - add test for host apex.
1490