• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2021 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	"regexp"
21	"strings"
22	"testing"
23
24	"android/soong/android"
25
26	"github.com/google/blueprint/proptools"
27)
28
29func TestJavaSdkLibrary(t *testing.T) {
30	result := android.GroupFixturePreparers(
31		prepareForJavaTest,
32		PrepareForTestWithJavaSdkLibraryFiles,
33		FixtureWithPrebuiltApis(map[string][]string{
34			"28": {"foo"},
35			"29": {"foo"},
36			"30": {"bar", "barney", "baz", "betty", "foo", "fred", "quuz", "wilma"},
37		}),
38	).RunTestWithBp(t, `
39		droiddoc_exported_dir {
40			name: "droiddoc-templates-sdk",
41			path: ".",
42		}
43		java_sdk_library {
44			name: "foo",
45			srcs: ["a.java", "b.java"],
46			api_packages: ["foo"],
47		}
48		java_sdk_library {
49			name: "bar",
50			srcs: ["a.java", "b.java"],
51			api_packages: ["bar"],
52			exclude_kotlinc_generated_files: true,
53		}
54		java_library {
55			name: "baz",
56			srcs: ["c.java"],
57			libs: ["foo", "bar.stubs"],
58			sdk_version: "system_current",
59		}
60		java_sdk_library {
61			name: "barney",
62			srcs: ["c.java"],
63			api_only: true,
64		}
65		java_sdk_library {
66			name: "betty",
67			srcs: ["c.java"],
68			shared_library: false,
69		}
70		java_sdk_library_import {
71		    name: "quuz",
72				public: {
73					jars: ["c.jar"],
74				},
75		}
76		java_sdk_library_import {
77		    name: "fred",
78				public: {
79					jars: ["b.jar"],
80				},
81		}
82		java_sdk_library_import {
83		    name: "wilma",
84				public: {
85					jars: ["b.jar"],
86				},
87				shared_library: false,
88		}
89		java_library {
90		    name: "qux",
91		    srcs: ["c.java"],
92		    libs: ["baz", "fred", "quuz.stubs", "wilma", "barney", "betty"],
93		    sdk_version: "system_current",
94		}
95		java_library {
96			name: "baz-test",
97			srcs: ["c.java"],
98			libs: ["foo"],
99			sdk_version: "test_current",
100		}
101		java_library {
102			name: "baz-29",
103			srcs: ["c.java"],
104			libs: ["foo"],
105			sdk_version: "system_29",
106		}
107		java_library {
108			name: "baz-module-30",
109			srcs: ["c.java"],
110			libs: ["foo"],
111			sdk_version: "module_30",
112		}
113	`)
114
115	// check the existence of the internal modules
116	foo := result.ModuleForTests("foo", "android_common")
117	result.ModuleForTests(apiScopePublic.stubsLibraryModuleName("foo"), "android_common")
118	result.ModuleForTests(apiScopeSystem.stubsLibraryModuleName("foo"), "android_common")
119	result.ModuleForTests(apiScopeTest.stubsLibraryModuleName("foo"), "android_common")
120	result.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo"), "android_common")
121	result.ModuleForTests(apiScopeSystem.stubsSourceModuleName("foo"), "android_common")
122	result.ModuleForTests(apiScopeTest.stubsSourceModuleName("foo"), "android_common")
123	result.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo")+".api.contribution", "")
124	result.ModuleForTests("foo"+sdkXmlFileSuffix, "android_common")
125	result.ModuleForTests("foo.api.public.28", "")
126	result.ModuleForTests("foo.api.system.28", "")
127	result.ModuleForTests("foo.api.test.28", "")
128
129	exportedComponentsInfo := result.ModuleProvider(foo.Module(), android.ExportedComponentsInfoProvider).(android.ExportedComponentsInfo)
130	expectedFooExportedComponents := []string{
131		"foo-removed.api.public.latest",
132		"foo-removed.api.system.latest",
133		"foo.api.public.latest",
134		"foo.api.system.latest",
135		"foo.stubs",
136		"foo.stubs.source",
137		"foo.stubs.source.system",
138		"foo.stubs.source.test",
139		"foo.stubs.system",
140		"foo.stubs.test",
141	}
142	android.AssertArrayString(t, "foo exported components", expectedFooExportedComponents, exportedComponentsInfo.Components)
143
144	bazJavac := result.ModuleForTests("baz", "android_common").Rule("javac")
145	// tests if baz is actually linked to the stubs lib
146	android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.system.jar")
147	// ... and not to the impl lib
148	android.AssertStringDoesNotContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.jar")
149	// test if baz is not linked to the system variant of foo
150	android.AssertStringDoesNotContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.jar")
151
152	bazTestJavac := result.ModuleForTests("baz-test", "android_common").Rule("javac")
153	// tests if baz-test is actually linked to the test stubs lib
154	android.AssertStringDoesContain(t, "baz-test javac classpath", bazTestJavac.Args["classpath"], "foo.stubs.test.jar")
155
156	baz29Javac := result.ModuleForTests("baz-29", "android_common").Rule("javac")
157	// tests if baz-29 is actually linked to the system 29 stubs lib
158	android.AssertStringDoesContain(t, "baz-29 javac classpath", baz29Javac.Args["classpath"], "prebuilts/sdk/29/system/foo.jar")
159
160	bazModule30Javac := result.ModuleForTests("baz-module-30", "android_common").Rule("javac")
161	// tests if "baz-module-30" is actually linked to the module 30 stubs lib
162	android.AssertStringDoesContain(t, "baz-module-30 javac classpath", bazModule30Javac.Args["classpath"], "prebuilts/sdk/30/module-lib/foo.jar")
163
164	// test if baz has exported SDK lib names foo and bar to qux
165	qux := result.ModuleForTests("qux", "android_common")
166	if quxLib, ok := qux.Module().(*Library); ok {
167		requiredSdkLibs, optionalSdkLibs := quxLib.ClassLoaderContexts().UsesLibs()
168		android.AssertDeepEquals(t, "qux exports (required)", []string{"fred", "quuz", "foo", "bar"}, requiredSdkLibs)
169		android.AssertDeepEquals(t, "qux exports (optional)", []string{}, optionalSdkLibs)
170	}
171
172	fooDexJar := result.ModuleForTests("foo", "android_common").Rule("d8")
173	// tests if kotlinc generated files are NOT excluded from output of foo.
174	android.AssertStringDoesNotContain(t, "foo dex", fooDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module")
175
176	barDexJar := result.ModuleForTests("bar", "android_common").Rule("d8")
177	// tests if kotlinc generated files are excluded from output of bar.
178	android.AssertStringDoesContain(t, "bar dex", barDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module")
179}
180
181func TestJavaSdkLibrary_UpdatableLibrary(t *testing.T) {
182	result := android.GroupFixturePreparers(
183		prepareForJavaTest,
184		PrepareForTestWithJavaSdkLibraryFiles,
185		FixtureWithPrebuiltApis(map[string][]string{
186			"28": {"foo"},
187			"29": {"foo"},
188			"30": {"foo", "fooUpdatable", "fooUpdatableErr"},
189		}),
190		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
191			variables.Platform_version_active_codenames = []string{"Tiramisu", "U", "V", "W", "X"}
192		}),
193	).RunTestWithBp(t,
194		`
195		java_sdk_library {
196			name: "fooUpdatable",
197			srcs: ["a.java", "b.java"],
198			api_packages: ["foo"],
199			on_bootclasspath_since: "U",
200			on_bootclasspath_before: "V",
201			min_device_sdk: "W",
202			max_device_sdk: "X",
203			min_sdk_version: "S",
204		}
205		java_sdk_library {
206			name: "foo",
207			srcs: ["a.java", "b.java"],
208			api_packages: ["foo"],
209		}
210`)
211
212	// test that updatability attributes are passed on correctly
213	fooUpdatable := result.ModuleForTests("fooUpdatable.xml", "android_common").Rule("java_sdk_xml")
214	android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `on-bootclasspath-since=\"U\"`)
215	android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `on-bootclasspath-before=\"V\"`)
216	android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `min-device-sdk=\"W\"`)
217	android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `max-device-sdk=\"X\"`)
218
219	// double check that updatability attributes are not written if they don't exist in the bp file
220	// the permissions file for the foo library defined above
221	fooPermissions := result.ModuleForTests("foo.xml", "android_common").Rule("java_sdk_xml")
222	android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `on-bootclasspath-since`)
223	android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `on-bootclasspath-before`)
224	android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `min-device-sdk`)
225	android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `max-device-sdk`)
226}
227
228func TestJavaSdkLibrary_UpdatableLibrary_Validation_ValidVersion(t *testing.T) {
229	android.GroupFixturePreparers(
230		prepareForJavaTest,
231		PrepareForTestWithJavaSdkLibraryFiles,
232		FixtureWithPrebuiltApis(map[string][]string{
233			"30": {"fooUpdatable", "fooUpdatableErr"},
234		}),
235	).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(
236		[]string{
237			`on_bootclasspath_since: "aaa" could not be parsed as an integer and is not a recognized codename`,
238			`on_bootclasspath_before: "bbc" could not be parsed as an integer and is not a recognized codename`,
239			`min_device_sdk: "ccc" could not be parsed as an integer and is not a recognized codename`,
240			`max_device_sdk: "current" is not an allowed value for this attribute`,
241		})).RunTestWithBp(t,
242		`
243	java_sdk_library {
244			name: "fooUpdatableErr",
245			srcs: ["a.java", "b.java"],
246			api_packages: ["foo"],
247			on_bootclasspath_since: "aaa",
248			on_bootclasspath_before: "bbc",
249			min_device_sdk: "ccc",
250			max_device_sdk: "current",
251		}
252`)
253}
254
255func TestJavaSdkLibrary_UpdatableLibrary_Validation_AtLeastTAttributes(t *testing.T) {
256	android.GroupFixturePreparers(
257		prepareForJavaTest,
258		PrepareForTestWithJavaSdkLibraryFiles,
259		FixtureWithPrebuiltApis(map[string][]string{
260			"28": {"foo"},
261		}),
262	).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(
263		[]string{
264			"on_bootclasspath_since: Attribute value needs to be at least T",
265			"on_bootclasspath_before: Attribute value needs to be at least T",
266			"min_device_sdk: Attribute value needs to be at least T",
267			"max_device_sdk: Attribute value needs to be at least T",
268		},
269	)).RunTestWithBp(t,
270		`
271		java_sdk_library {
272			name: "foo",
273			srcs: ["a.java", "b.java"],
274			api_packages: ["foo"],
275			on_bootclasspath_since: "S",
276			on_bootclasspath_before: "S",
277			min_device_sdk: "S",
278			max_device_sdk: "S",
279			min_sdk_version: "S",
280		}
281`)
282}
283
284func TestJavaSdkLibrary_UpdatableLibrary_Validation_MinAndMaxDeviceSdk(t *testing.T) {
285	android.GroupFixturePreparers(
286		prepareForJavaTest,
287		PrepareForTestWithJavaSdkLibraryFiles,
288		FixtureWithPrebuiltApis(map[string][]string{
289			"28": {"foo"},
290		}),
291		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
292			variables.Platform_version_active_codenames = []string{"Tiramisu", "U", "V"}
293		}),
294	).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(
295		[]string{
296			"min_device_sdk can't be greater than max_device_sdk",
297		},
298	)).RunTestWithBp(t,
299		`
300		java_sdk_library {
301			name: "foo",
302			srcs: ["a.java", "b.java"],
303			api_packages: ["foo"],
304			min_device_sdk: "V",
305			max_device_sdk: "U",
306			min_sdk_version: "S",
307		}
308`)
309}
310
311func TestJavaSdkLibrary_UpdatableLibrary_Validation_MinAndMaxDeviceSdkAndModuleMinSdk(t *testing.T) {
312	android.GroupFixturePreparers(
313		prepareForJavaTest,
314		PrepareForTestWithJavaSdkLibraryFiles,
315		FixtureWithPrebuiltApis(map[string][]string{
316			"28": {"foo"},
317		}),
318		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
319			variables.Platform_version_active_codenames = []string{"Tiramisu", "U", "V"}
320		}),
321	).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(
322		[]string{
323			regexp.QuoteMeta("min_device_sdk: Can't be less than module's min sdk (V)"),
324			regexp.QuoteMeta("max_device_sdk: Can't be less than module's min sdk (V)"),
325		},
326	)).RunTestWithBp(t,
327		`
328		java_sdk_library {
329			name: "foo",
330			srcs: ["a.java", "b.java"],
331			api_packages: ["foo"],
332			min_device_sdk: "U",
333			max_device_sdk: "U",
334			min_sdk_version: "V",
335		}
336`)
337}
338
339func TestJavaSdkLibrary_UpdatableLibrary_usesNewTag(t *testing.T) {
340	result := android.GroupFixturePreparers(
341		prepareForJavaTest,
342		PrepareForTestWithJavaSdkLibraryFiles,
343		FixtureWithPrebuiltApis(map[string][]string{
344			"30": {"foo"},
345		}),
346	).RunTestWithBp(t,
347		`
348		java_sdk_library {
349			name: "foo",
350			srcs: ["a.java", "b.java"],
351			min_device_sdk: "Tiramisu",
352			min_sdk_version: "S",
353		}
354`)
355	// test that updatability attributes are passed on correctly
356	fooUpdatable := result.ModuleForTests("foo.xml", "android_common").Rule("java_sdk_xml")
357	android.AssertStringDoesContain(t, "foo.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `<apex-library`)
358	android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `<library`)
359}
360
361func TestJavaSdkLibrary_StubOrImplOnlyLibs(t *testing.T) {
362	result := android.GroupFixturePreparers(
363		prepareForJavaTest,
364		PrepareForTestWithJavaSdkLibraryFiles,
365		FixtureWithLastReleaseApis("sdklib"),
366	).RunTestWithBp(t, `
367		java_sdk_library {
368			name: "sdklib",
369			srcs: ["a.java"],
370			libs: ["lib"],
371			static_libs: ["static-lib"],
372			impl_only_libs: ["impl-only-lib"],
373			stub_only_libs: ["stub-only-lib"],
374			stub_only_static_libs: ["stub-only-static-lib"],
375		}
376		java_defaults {
377			name: "defaults",
378			srcs: ["a.java"],
379			sdk_version: "current",
380		}
381		java_library { name: "lib", defaults: ["defaults"] }
382		java_library { name: "static-lib", defaults: ["defaults"] }
383		java_library { name: "impl-only-lib", defaults: ["defaults"] }
384		java_library { name: "stub-only-lib", defaults: ["defaults"] }
385		java_library { name: "stub-only-static-lib", defaults: ["defaults"] }
386		`)
387	var expectations = []struct {
388		lib               string
389		on_impl_classpath bool
390		on_stub_classpath bool
391		in_impl_combined  bool
392		in_stub_combined  bool
393	}{
394		{lib: "lib", on_impl_classpath: true},
395		{lib: "static-lib", in_impl_combined: true},
396		{lib: "impl-only-lib", on_impl_classpath: true},
397		{lib: "stub-only-lib", on_stub_classpath: true},
398		{lib: "stub-only-static-lib", in_stub_combined: true},
399	}
400	verify := func(sdklib, dep string, cp, combined bool) {
401		sdklibCp := result.ModuleForTests(sdklib, "android_common").Rule("javac").Args["classpath"]
402		expected := cp || combined // Every combined jar is also on the classpath.
403		android.AssertStringContainsEquals(t, "bad classpath for "+sdklib, sdklibCp, "/"+dep+".jar", expected)
404
405		combineJarInputs := result.ModuleForTests(sdklib, "android_common").Rule("combineJar").Inputs.Strings()
406		depPath := filepath.Join("out", "soong", ".intermediates", dep, "android_common", "turbine-combined", dep+".jar")
407		android.AssertStringListContainsEquals(t, "bad combined inputs for "+sdklib, combineJarInputs, depPath, combined)
408	}
409	for _, expectation := range expectations {
410		verify("sdklib", expectation.lib, expectation.on_impl_classpath, expectation.in_impl_combined)
411		verify("sdklib.impl", expectation.lib, expectation.on_impl_classpath, expectation.in_impl_combined)
412
413		stubName := apiScopePublic.stubsLibraryModuleName("sdklib")
414		verify(stubName, expectation.lib, expectation.on_stub_classpath, expectation.in_stub_combined)
415	}
416}
417
418func TestJavaSdkLibrary_DoNotAccessImplWhenItIsNotBuilt(t *testing.T) {
419	result := android.GroupFixturePreparers(
420		prepareForJavaTest,
421		PrepareForTestWithJavaSdkLibraryFiles,
422		FixtureWithLastReleaseApis("foo"),
423	).RunTestWithBp(t, `
424		java_sdk_library {
425			name: "foo",
426			srcs: ["a.java"],
427			api_only: true,
428			public: {
429				enabled: true,
430			},
431		}
432
433		java_library {
434			name: "bar",
435			srcs: ["b.java"],
436			libs: ["foo"],
437		}
438		`)
439
440	// The bar library should depend on the stubs jar.
441	barLibrary := result.ModuleForTests("bar", "android_common").Rule("javac")
442	if expected, actual := `^-classpath .*:out/soong/[^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
443		t.Errorf("expected %q, found %#q", expected, actual)
444	}
445}
446
447func TestJavaSdkLibrary_AccessOutputFiles(t *testing.T) {
448	android.GroupFixturePreparers(
449		prepareForJavaTest,
450		PrepareForTestWithJavaSdkLibraryFiles,
451		FixtureWithLastReleaseApis("foo"),
452	).RunTestWithBp(t, `
453		java_sdk_library {
454			name: "foo",
455			srcs: ["a.java"],
456			api_packages: ["foo"],
457			annotations_enabled: true,
458			public: {
459				enabled: true,
460			},
461		}
462		java_library {
463			name: "bar",
464			srcs: ["b.java", ":foo{.public.stubs.source}"],
465			java_resources: [":foo{.public.annotations.zip}"],
466		}
467		`)
468}
469
470func TestJavaSdkLibrary_AccessOutputFiles_NoAnnotations(t *testing.T) {
471	android.GroupFixturePreparers(
472		prepareForJavaTest,
473		PrepareForTestWithJavaSdkLibraryFiles,
474		FixtureWithLastReleaseApis("foo"),
475	).
476		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": path dependency ":foo{.public.annotations.zip}": annotations.zip not available for api scope public`)).
477		RunTestWithBp(t, `
478		java_sdk_library {
479			name: "foo",
480			srcs: ["a.java"],
481			api_packages: ["foo"],
482			public: {
483				enabled: true,
484			},
485		}
486
487		java_library {
488			name: "bar",
489			srcs: ["b.java", ":foo{.public.stubs.source}"],
490			java_resources: [":foo{.public.annotations.zip}"],
491		}
492		`)
493}
494
495func TestJavaSdkLibrary_AccessOutputFiles_MissingScope(t *testing.T) {
496	android.GroupFixturePreparers(
497		prepareForJavaTest,
498		PrepareForTestWithJavaSdkLibraryFiles,
499		FixtureWithLastReleaseApis("foo"),
500	).
501		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`"foo" does not provide api scope system`)).
502		RunTestWithBp(t, `
503		java_sdk_library {
504			name: "foo",
505			srcs: ["a.java"],
506			api_packages: ["foo"],
507			public: {
508				enabled: true,
509			},
510		}
511
512		java_library {
513			name: "bar",
514			srcs: ["b.java", ":foo{.system.stubs.source}"],
515		}
516		`)
517}
518
519func TestJavaSdkLibrary_Deps(t *testing.T) {
520	result := android.GroupFixturePreparers(
521		prepareForJavaTest,
522		PrepareForTestWithJavaSdkLibraryFiles,
523		FixtureWithLastReleaseApis("sdklib"),
524	).RunTestWithBp(t, `
525		java_sdk_library {
526			name: "sdklib",
527			srcs: ["a.java"],
528			sdk_version: "none",
529			system_modules: "none",
530			public: {
531				enabled: true,
532			},
533		}
534		`)
535
536	CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{
537		`dex2oatd`,
538		`sdklib-removed.api.public.latest`,
539		`sdklib.api.public.latest`,
540		`sdklib.impl`,
541		`sdklib.stubs`,
542		`sdklib.stubs.source`,
543		`sdklib.xml`,
544	})
545}
546
547func TestJavaSdkLibraryImport_AccessOutputFiles(t *testing.T) {
548	prepareForJavaTest.RunTestWithBp(t, `
549		java_sdk_library_import {
550			name: "foo",
551			public: {
552				jars: ["a.jar"],
553				stub_srcs: ["a.java"],
554				current_api: "api/current.txt",
555				removed_api: "api/removed.txt",
556				annotations: "x/annotations.zip",
557			},
558		}
559
560		java_library {
561			name: "bar",
562			srcs: [":foo{.public.stubs.source}"],
563			java_resources: [
564				":foo{.public.api.txt}",
565				":foo{.public.removed-api.txt}",
566				":foo{.public.annotations.zip}",
567			],
568		}
569		`)
570}
571
572func TestJavaSdkLibraryImport_AccessOutputFiles_Invalid(t *testing.T) {
573	bp := `
574		java_sdk_library_import {
575			name: "foo",
576			public: {
577				jars: ["a.jar"],
578			},
579		}
580		`
581
582	t.Run("stubs.source", func(t *testing.T) {
583		prepareForJavaTest.
584			ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`stubs.source not available for api scope public`)).
585			RunTestWithBp(t, bp+`
586				java_library {
587					name: "bar",
588					srcs: [":foo{.public.stubs.source}"],
589					java_resources: [
590						":foo{.public.api.txt}",
591						":foo{.public.removed-api.txt}",
592					],
593				}
594			`)
595	})
596
597	t.Run("api.txt", func(t *testing.T) {
598		prepareForJavaTest.
599			ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`api.txt not available for api scope public`)).
600			RunTestWithBp(t, bp+`
601				java_library {
602					name: "bar",
603					srcs: ["a.java"],
604					java_resources: [
605						":foo{.public.api.txt}",
606					],
607				}
608			`)
609	})
610
611	t.Run("removed-api.txt", func(t *testing.T) {
612		prepareForJavaTest.
613			ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`removed-api.txt not available for api scope public`)).
614			RunTestWithBp(t, bp+`
615				java_library {
616					name: "bar",
617					srcs: ["a.java"],
618					java_resources: [
619						":foo{.public.removed-api.txt}",
620					],
621				}
622			`)
623	})
624}
625
626func TestJavaSdkLibrary_InvalidScopes(t *testing.T) {
627	prepareForJavaTest.
628		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo": enabled api scope "system" depends on disabled scope "public"`)).
629		RunTestWithBp(t, `
630			java_sdk_library {
631				name: "foo",
632				srcs: ["a.java", "b.java"],
633				api_packages: ["foo"],
634				// Explicitly disable public to test the check that ensures the set of enabled
635				// scopes is consistent.
636				public: {
637					enabled: false,
638				},
639				system: {
640					enabled: true,
641				},
642			}
643		`)
644}
645
646func TestJavaSdkLibrary_SdkVersion_ForScope(t *testing.T) {
647	android.GroupFixturePreparers(
648		prepareForJavaTest,
649		PrepareForTestWithJavaSdkLibraryFiles,
650		FixtureWithLastReleaseApis("foo"),
651	).RunTestWithBp(t, `
652		java_sdk_library {
653			name: "foo",
654			srcs: ["a.java", "b.java"],
655			api_packages: ["foo"],
656			system: {
657				enabled: true,
658				sdk_version: "module_current",
659			},
660		}
661		`)
662}
663
664func TestJavaSdkLibrary_ModuleLib(t *testing.T) {
665	android.GroupFixturePreparers(
666		prepareForJavaTest,
667		PrepareForTestWithJavaSdkLibraryFiles,
668		FixtureWithLastReleaseApis("foo"),
669	).RunTestWithBp(t, `
670		java_sdk_library {
671			name: "foo",
672			srcs: ["a.java", "b.java"],
673			api_packages: ["foo"],
674			system: {
675				enabled: true,
676			},
677			module_lib: {
678				enabled: true,
679			},
680		}
681		`)
682}
683
684func TestJavaSdkLibrary_SystemServer(t *testing.T) {
685	android.GroupFixturePreparers(
686		prepareForJavaTest,
687		PrepareForTestWithJavaSdkLibraryFiles,
688		FixtureWithLastReleaseApis("foo"),
689	).RunTestWithBp(t, `
690		java_sdk_library {
691			name: "foo",
692			srcs: ["a.java", "b.java"],
693			api_packages: ["foo"],
694			system: {
695				enabled: true,
696			},
697			system_server: {
698				enabled: true,
699			},
700		}
701		`)
702}
703
704func TestJavaSdkLibrary_SystemServer_AccessToStubScopeLibs(t *testing.T) {
705	result := android.GroupFixturePreparers(
706		prepareForJavaTest,
707		PrepareForTestWithJavaSdkLibraryFiles,
708		FixtureWithLastReleaseApis("foo-public", "foo-system", "foo-module-lib", "foo-system-server"),
709	).RunTestWithBp(t, `
710		java_sdk_library {
711			name: "foo-public",
712			srcs: ["a.java"],
713			api_packages: ["foo"],
714			public: {
715				enabled: true,
716			},
717		}
718
719		java_sdk_library {
720			name: "foo-system",
721			srcs: ["a.java"],
722			api_packages: ["foo"],
723			system: {
724				enabled: true,
725			},
726		}
727
728		java_sdk_library {
729			name: "foo-module-lib",
730			srcs: ["a.java"],
731			api_packages: ["foo"],
732			system: {
733				enabled: true,
734			},
735			module_lib: {
736				enabled: true,
737			},
738		}
739
740		java_sdk_library {
741			name: "foo-system-server",
742			srcs: ["a.java"],
743			api_packages: ["foo"],
744			system_server: {
745				enabled: true,
746			},
747		}
748
749		java_library {
750			name: "bar",
751			srcs: ["a.java"],
752			libs: ["foo-public", "foo-system", "foo-module-lib", "foo-system-server"],
753			sdk_version: "system_server_current",
754		}
755		`)
756
757	stubsPath := func(name string, scope *apiScope) string {
758		name = scope.stubsLibraryModuleName(name)
759		return fmt.Sprintf("out/soong/.intermediates/%[1]s/android_common/turbine-combined/%[1]s.jar", name)
760	}
761
762	// The bar library should depend on the highest (where system server is highest and public is
763	// lowest) API scopes provided by each of the foo-* modules. The highest API scope provided by the
764	// foo-<x> module is <x>.
765	barLibrary := result.ModuleForTests("bar", "android_common").Rule("javac")
766	stubLibraries := []string{
767		stubsPath("foo-public", apiScopePublic),
768		stubsPath("foo-system", apiScopeSystem),
769		stubsPath("foo-module-lib", apiScopeModuleLib),
770		stubsPath("foo-system-server", apiScopeSystemServer),
771	}
772	expectedPattern := fmt.Sprintf(`^-classpath .*:\Q%s\E$`, strings.Join(stubLibraries, ":"))
773	if expected, actual := expectedPattern, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
774		t.Errorf("expected pattern %q to match %#q", expected, actual)
775	}
776}
777
778func TestJavaSdkLibrary_MissingScope(t *testing.T) {
779	prepareForJavaTest.
780		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`requires api scope module-lib from foo but it only has \[\] available`)).
781		RunTestWithBp(t, `
782			java_sdk_library {
783				name: "foo",
784				srcs: ["a.java"],
785				public: {
786					enabled: false,
787				},
788			}
789
790			java_library {
791				name: "baz",
792				srcs: ["a.java"],
793				libs: ["foo"],
794				sdk_version: "module_current",
795			}
796		`)
797}
798
799func TestJavaSdkLibrary_FallbackScope(t *testing.T) {
800	android.GroupFixturePreparers(
801		prepareForJavaTest,
802		PrepareForTestWithJavaSdkLibraryFiles,
803		FixtureWithLastReleaseApis("foo"),
804	).RunTestWithBp(t, `
805		java_sdk_library {
806			name: "foo",
807			srcs: ["a.java"],
808			system: {
809				enabled: true,
810			},
811		}
812
813		java_library {
814			name: "baz",
815			srcs: ["a.java"],
816			libs: ["foo"],
817			// foo does not have module-lib scope so it should fallback to system
818			sdk_version: "module_current",
819		}
820		`)
821}
822
823func TestJavaSdkLibrary_DefaultToStubs(t *testing.T) {
824	result := android.GroupFixturePreparers(
825		prepareForJavaTest,
826		PrepareForTestWithJavaSdkLibraryFiles,
827		FixtureWithLastReleaseApis("foo"),
828	).RunTestWithBp(t, `
829		java_sdk_library {
830			name: "foo",
831			srcs: ["a.java"],
832			system: {
833				enabled: true,
834			},
835			default_to_stubs: true,
836		}
837
838		java_library {
839			name: "baz",
840			srcs: ["a.java"],
841			libs: ["foo"],
842			// does not have sdk_version set, should fallback to module,
843			// which will then fallback to system because the module scope
844			// is not enabled.
845		}
846		`)
847	// The baz library should depend on the system stubs jar.
848	bazLibrary := result.ModuleForTests("baz", "android_common").Rule("javac")
849	if expected, actual := `^-classpath .*:out/soong/[^:]*/turbine-combined/foo\.stubs.system\.jar$`, bazLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
850		t.Errorf("expected %q, found %#q", expected, actual)
851	}
852}
853
854func TestJavaSdkLibraryImport(t *testing.T) {
855	result := prepareForJavaTest.RunTestWithBp(t, `
856		java_library {
857			name: "foo",
858			srcs: ["a.java"],
859			libs: ["sdklib"],
860			sdk_version: "current",
861		}
862
863		java_library {
864			name: "foo.system",
865			srcs: ["a.java"],
866			libs: ["sdklib"],
867			sdk_version: "system_current",
868		}
869
870		java_library {
871			name: "foo.test",
872			srcs: ["a.java"],
873			libs: ["sdklib"],
874			sdk_version: "test_current",
875		}
876
877		java_sdk_library_import {
878			name: "sdklib",
879			public: {
880				jars: ["a.jar"],
881			},
882			system: {
883				jars: ["b.jar"],
884			},
885			test: {
886				jars: ["c.jar"],
887				stub_srcs: ["c.java"],
888			},
889		}
890		`)
891
892	for _, scope := range []string{"", ".system", ".test"} {
893		fooModule := result.ModuleForTests("foo"+scope, "android_common")
894		javac := fooModule.Rule("javac")
895
896		sdklibStubsJar := result.ModuleForTests("sdklib.stubs"+scope, "android_common").Rule("combineJar").Output
897		android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], sdklibStubsJar.String())
898	}
899
900	CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{
901		`dex2oatd`,
902		`prebuilt_sdklib.stubs`,
903		`prebuilt_sdklib.stubs.source.test`,
904		`prebuilt_sdklib.stubs.system`,
905		`prebuilt_sdklib.stubs.test`,
906	})
907}
908
909func TestJavaSdkLibraryImport_WithSource(t *testing.T) {
910	result := android.GroupFixturePreparers(
911		prepareForJavaTest,
912		PrepareForTestWithJavaSdkLibraryFiles,
913		FixtureWithLastReleaseApis("sdklib"),
914	).RunTestWithBp(t, `
915		java_sdk_library {
916			name: "sdklib",
917			srcs: ["a.java"],
918			sdk_version: "none",
919			system_modules: "none",
920			public: {
921				enabled: true,
922			},
923		}
924
925		java_sdk_library_import {
926			name: "sdklib",
927			public: {
928				jars: ["a.jar"],
929			},
930		}
931		`)
932
933	CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{
934		`dex2oatd`,
935		`prebuilt_sdklib`,
936		`sdklib-removed.api.public.latest`,
937		`sdklib.api.public.latest`,
938		`sdklib.impl`,
939		`sdklib.stubs`,
940		`sdklib.stubs.source`,
941		`sdklib.xml`,
942	})
943
944	CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{
945		`prebuilt_sdklib.stubs`,
946		`sdklib.impl`,
947		// This should be prebuilt_sdklib.stubs but is set to sdklib.stubs because the
948		// dependency is added after prebuilts may have been renamed and so has to use
949		// the renamed name.
950		`sdklib.xml`,
951	})
952}
953
954func testJavaSdkLibraryImport_Preferred(t *testing.T, prefer string, preparer android.FixturePreparer) {
955	result := android.GroupFixturePreparers(
956		prepareForJavaTest,
957		PrepareForTestWithJavaSdkLibraryFiles,
958		FixtureWithLastReleaseApis("sdklib"),
959		preparer,
960	).RunTestWithBp(t, `
961		java_sdk_library {
962			name: "sdklib",
963			srcs: ["a.java"],
964			sdk_version: "none",
965			system_modules: "none",
966			public: {
967				enabled: true,
968			},
969		}
970
971		java_sdk_library_import {
972			name: "sdklib",
973			`+prefer+`
974			public: {
975				jars: ["a.jar"],
976				stub_srcs: ["a.java"],
977				current_api: "current.txt",
978				removed_api: "removed.txt",
979				annotations: "annotations.zip",
980			},
981		}
982
983		java_library {
984			name: "combined",
985			static_libs: [
986				"sdklib.stubs",
987			],
988			java_resources: [
989				":sdklib.stubs.source",
990				":sdklib{.public.api.txt}",
991				":sdklib{.public.removed-api.txt}",
992				":sdklib{.public.annotations.zip}",
993			],
994			sdk_version: "none",
995			system_modules: "none",
996		}
997
998		java_library {
999			name: "public",
1000			srcs: ["a.java"],
1001			libs: ["sdklib"],
1002			sdk_version: "current",
1003		}
1004		`)
1005
1006	CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{
1007		`prebuilt_sdklib`,
1008		`sdklib-removed.api.public.latest`,
1009		`sdklib.api.public.latest`,
1010		`sdklib.impl`,
1011		`sdklib.stubs`,
1012		`sdklib.stubs.source`,
1013		`sdklib.xml`,
1014	})
1015
1016	CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{
1017		`dex2oatd`,
1018		`prebuilt_sdklib.stubs`,
1019		`prebuilt_sdklib.stubs.source`,
1020		`sdklib.impl`,
1021		`sdklib.xml`,
1022	})
1023
1024	// Make sure that dependencies on child modules use the prebuilt when preferred.
1025	CheckModuleDependencies(t, result.TestContext, "combined", "android_common", []string{
1026		// Each use of :sdklib{...} adds a dependency onto prebuilt_sdklib.
1027		`prebuilt_sdklib`,
1028		`prebuilt_sdklib`,
1029		`prebuilt_sdklib`,
1030		`prebuilt_sdklib.stubs`,
1031		`prebuilt_sdklib.stubs.source`,
1032	})
1033
1034	// Make sure that dependencies on sdklib that resolve to one of the child libraries use the
1035	// prebuilt library.
1036	public := result.ModuleForTests("public", "android_common")
1037	rule := public.Output("javac/public.jar")
1038	inputs := rule.Implicits.Strings()
1039	expected := "out/soong/.intermediates/prebuilt_sdklib.stubs/android_common/combined/sdklib.stubs.jar"
1040	if !android.InList(expected, inputs) {
1041		t.Errorf("expected %q to contain %q", inputs, expected)
1042	}
1043}
1044
1045func TestJavaSdkLibraryImport_Preferred(t *testing.T) {
1046	t.Run("prefer", func(t *testing.T) {
1047		testJavaSdkLibraryImport_Preferred(t, "prefer: true,", android.NullFixturePreparer)
1048	})
1049
1050	t.Run("use_source_config_var", func(t *testing.T) {
1051		testJavaSdkLibraryImport_Preferred(t,
1052			"use_source_config_var: {config_namespace: \"acme\", var_name: \"use_source\"},",
1053			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1054				variables.VendorVars = map[string]map[string]string{
1055					"acme": {
1056						"use_source": "false",
1057					},
1058				}
1059			}))
1060	})
1061}
1062
1063func TestJavaSdkLibraryEnforce(t *testing.T) {
1064	partitionToBpOption := func(partition string) string {
1065		switch partition {
1066		case "system":
1067			return ""
1068		case "vendor":
1069			return "soc_specific: true,"
1070		case "product":
1071			return "product_specific: true,"
1072		default:
1073			panic("Invalid partition group name: " + partition)
1074		}
1075	}
1076
1077	type testConfigInfo struct {
1078		libraryType                string
1079		fromPartition              string
1080		toPartition                string
1081		enforceVendorInterface     bool
1082		enforceProductInterface    bool
1083		enforceJavaSdkLibraryCheck bool
1084		allowList                  []string
1085	}
1086
1087	createPreparer := func(info testConfigInfo) android.FixturePreparer {
1088		bpFileTemplate := `
1089			java_library {
1090				name: "foo",
1091				srcs: ["foo.java"],
1092				libs: ["bar"],
1093				sdk_version: "current",
1094				%s
1095			}
1096
1097			%s {
1098				name: "bar",
1099				srcs: ["bar.java"],
1100				sdk_version: "current",
1101				%s
1102			}
1103		`
1104
1105		bpFile := fmt.Sprintf(bpFileTemplate,
1106			partitionToBpOption(info.fromPartition),
1107			info.libraryType,
1108			partitionToBpOption(info.toPartition))
1109
1110		return android.GroupFixturePreparers(
1111			PrepareForTestWithJavaSdkLibraryFiles,
1112			FixtureWithLastReleaseApis("bar"),
1113			android.FixtureWithRootAndroidBp(bpFile),
1114			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1115				variables.EnforceProductPartitionInterface = proptools.BoolPtr(info.enforceProductInterface)
1116				if info.enforceVendorInterface {
1117					variables.DeviceVndkVersion = proptools.StringPtr("current")
1118				}
1119				variables.EnforceInterPartitionJavaSdkLibrary = proptools.BoolPtr(info.enforceJavaSdkLibraryCheck)
1120				variables.InterPartitionJavaLibraryAllowList = info.allowList
1121			}),
1122		)
1123	}
1124
1125	runTest := func(t *testing.T, info testConfigInfo, expectedErrorPattern string) {
1126		t.Run(fmt.Sprintf("%v", info), func(t *testing.T) {
1127			errorHandler := android.FixtureExpectsNoErrors
1128			if expectedErrorPattern != "" {
1129				errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(expectedErrorPattern)
1130			}
1131			android.GroupFixturePreparers(
1132				prepareForJavaTest,
1133				createPreparer(info),
1134			).
1135				ExtendWithErrorHandler(errorHandler).
1136				RunTest(t)
1137		})
1138	}
1139
1140	errorMessage := "is not allowed across the partitions"
1141
1142	runTest(t, testConfigInfo{
1143		libraryType:                "java_library",
1144		fromPartition:              "product",
1145		toPartition:                "system",
1146		enforceVendorInterface:     true,
1147		enforceProductInterface:    true,
1148		enforceJavaSdkLibraryCheck: false,
1149	}, "")
1150
1151	runTest(t, testConfigInfo{
1152		libraryType:                "java_library",
1153		fromPartition:              "product",
1154		toPartition:                "system",
1155		enforceVendorInterface:     true,
1156		enforceProductInterface:    false,
1157		enforceJavaSdkLibraryCheck: true,
1158	}, "")
1159
1160	runTest(t, testConfigInfo{
1161		libraryType:                "java_library",
1162		fromPartition:              "product",
1163		toPartition:                "system",
1164		enforceVendorInterface:     true,
1165		enforceProductInterface:    true,
1166		enforceJavaSdkLibraryCheck: true,
1167	}, errorMessage)
1168
1169	runTest(t, testConfigInfo{
1170		libraryType:                "java_library",
1171		fromPartition:              "vendor",
1172		toPartition:                "system",
1173		enforceVendorInterface:     true,
1174		enforceProductInterface:    true,
1175		enforceJavaSdkLibraryCheck: true,
1176	}, errorMessage)
1177
1178	runTest(t, testConfigInfo{
1179		libraryType:                "java_library",
1180		fromPartition:              "vendor",
1181		toPartition:                "system",
1182		enforceVendorInterface:     true,
1183		enforceProductInterface:    true,
1184		enforceJavaSdkLibraryCheck: true,
1185		allowList:                  []string{"bar"},
1186	}, "")
1187
1188	runTest(t, testConfigInfo{
1189		libraryType:                "java_library",
1190		fromPartition:              "vendor",
1191		toPartition:                "product",
1192		enforceVendorInterface:     true,
1193		enforceProductInterface:    true,
1194		enforceJavaSdkLibraryCheck: true,
1195	}, errorMessage)
1196
1197	runTest(t, testConfigInfo{
1198		libraryType:                "java_sdk_library",
1199		fromPartition:              "product",
1200		toPartition:                "system",
1201		enforceVendorInterface:     true,
1202		enforceProductInterface:    true,
1203		enforceJavaSdkLibraryCheck: true,
1204	}, "")
1205
1206	runTest(t, testConfigInfo{
1207		libraryType:                "java_sdk_library",
1208		fromPartition:              "vendor",
1209		toPartition:                "system",
1210		enforceVendorInterface:     true,
1211		enforceProductInterface:    true,
1212		enforceJavaSdkLibraryCheck: true,
1213	}, "")
1214
1215	runTest(t, testConfigInfo{
1216		libraryType:                "java_sdk_library",
1217		fromPartition:              "vendor",
1218		toPartition:                "product",
1219		enforceVendorInterface:     true,
1220		enforceProductInterface:    true,
1221		enforceJavaSdkLibraryCheck: true,
1222	}, "")
1223}
1224
1225func TestJavaSdkLibraryDist(t *testing.T) {
1226	result := android.GroupFixturePreparers(
1227		PrepareForTestWithJavaBuildComponents,
1228		PrepareForTestWithJavaDefaultModules,
1229		PrepareForTestWithJavaSdkLibraryFiles,
1230		FixtureWithLastReleaseApis(
1231			"sdklib_no_group",
1232			"sdklib_group_foo",
1233			"sdklib_owner_foo",
1234			"foo"),
1235	).RunTestWithBp(t, `
1236		java_sdk_library {
1237			name: "sdklib_no_group",
1238			srcs: ["foo.java"],
1239		}
1240
1241		java_sdk_library {
1242			name: "sdklib_group_foo",
1243			srcs: ["foo.java"],
1244			dist_group: "foo",
1245		}
1246
1247		java_sdk_library {
1248			name: "sdklib_owner_foo",
1249			srcs: ["foo.java"],
1250			owner: "foo",
1251		}
1252
1253		java_sdk_library {
1254			name: "sdklib_stem_foo",
1255			srcs: ["foo.java"],
1256			dist_stem: "foo",
1257		}
1258	`)
1259
1260	type testCase struct {
1261		module   string
1262		distDir  string
1263		distStem string
1264	}
1265	testCases := []testCase{
1266		{
1267			module:   "sdklib_no_group",
1268			distDir:  "apistubs/unknown/public",
1269			distStem: "sdklib_no_group.jar",
1270		},
1271		{
1272			module:   "sdklib_group_foo",
1273			distDir:  "apistubs/foo/public",
1274			distStem: "sdklib_group_foo.jar",
1275		},
1276		{
1277			// Owner doesn't affect distDir after b/186723288.
1278			module:   "sdklib_owner_foo",
1279			distDir:  "apistubs/unknown/public",
1280			distStem: "sdklib_owner_foo.jar",
1281		},
1282		{
1283			module:   "sdklib_stem_foo",
1284			distDir:  "apistubs/unknown/public",
1285			distStem: "foo.jar",
1286		},
1287	}
1288
1289	for _, tt := range testCases {
1290		t.Run(tt.module, func(t *testing.T) {
1291			m := result.ModuleForTests(tt.module+".stubs", "android_common").Module().(*Library)
1292			dists := m.Dists()
1293			if len(dists) != 1 {
1294				t.Fatalf("expected exactly 1 dist entry, got %d", len(dists))
1295			}
1296			if g, w := String(dists[0].Dir), tt.distDir; g != w {
1297				t.Errorf("expected dist dir %q, got %q", w, g)
1298			}
1299			if g, w := String(dists[0].Dest), tt.distStem; g != w {
1300				t.Errorf("expected dist stem %q, got %q", w, g)
1301			}
1302		})
1303	}
1304}
1305
1306func TestSdkLibrary_CheckMinSdkVersion(t *testing.T) {
1307	preparer := android.GroupFixturePreparers(
1308		PrepareForTestWithJavaBuildComponents,
1309		PrepareForTestWithJavaDefaultModules,
1310		PrepareForTestWithJavaSdkLibraryFiles,
1311	)
1312
1313	preparer.RunTestWithBp(t, `
1314		java_sdk_library {
1315			name: "sdklib",
1316            srcs: ["a.java"],
1317            static_libs: ["util"],
1318            min_sdk_version: "30",
1319			unsafe_ignore_missing_latest_api: true,
1320        }
1321
1322		java_library {
1323			name: "util",
1324			srcs: ["a.java"],
1325			min_sdk_version: "30",
1326		}
1327	`)
1328
1329	preparer.
1330		RunTestWithBp(t, `
1331			java_sdk_library {
1332				name: "sdklib",
1333				srcs: ["a.java"],
1334				libs: ["util"],
1335				impl_only_libs: ["util"],
1336				stub_only_libs: ["util"],
1337				stub_only_static_libs: ["util"],
1338				min_sdk_version: "30",
1339				unsafe_ignore_missing_latest_api: true,
1340			}
1341
1342			java_library {
1343				name: "util",
1344				srcs: ["a.java"],
1345			}
1346		`)
1347
1348	preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "util".*should support min_sdk_version\(30\)`)).
1349		RunTestWithBp(t, `
1350			java_sdk_library {
1351				name: "sdklib",
1352				srcs: ["a.java"],
1353				static_libs: ["util"],
1354				min_sdk_version: "30",
1355				unsafe_ignore_missing_latest_api: true,
1356			}
1357
1358			java_library {
1359				name: "util",
1360				srcs: ["a.java"],
1361				min_sdk_version: "31",
1362			}
1363		`)
1364
1365	preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "another_util".*should support min_sdk_version\(30\)`)).
1366		RunTestWithBp(t, `
1367			java_sdk_library {
1368				name: "sdklib",
1369				srcs: ["a.java"],
1370				static_libs: ["util"],
1371				min_sdk_version: "30",
1372				unsafe_ignore_missing_latest_api: true,
1373			}
1374
1375			java_library {
1376				name: "util",
1377				srcs: ["a.java"],
1378				static_libs: ["another_util"],
1379				min_sdk_version: "30",
1380			}
1381
1382			java_library {
1383				name: "another_util",
1384				srcs: ["a.java"],
1385				min_sdk_version: "31",
1386			}
1387		`)
1388}
1389
1390func TestJavaSdkLibrary_StubOnlyLibs_PassedToDroidstubs(t *testing.T) {
1391	result := android.GroupFixturePreparers(
1392		prepareForJavaTest,
1393		PrepareForTestWithJavaSdkLibraryFiles,
1394		FixtureWithLastReleaseApis("foo"),
1395	).RunTestWithBp(t, `
1396		java_sdk_library {
1397			name: "foo",
1398			srcs: ["a.java"],
1399			public: {
1400				enabled: true,
1401			},
1402			stub_only_libs: ["bar-lib"],
1403		}
1404
1405		java_library {
1406			name: "bar-lib",
1407			srcs: ["b.java"],
1408		}
1409		`)
1410
1411	// The foo.stubs.source should depend on bar-lib
1412	fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs)
1413	android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs, "bar-lib")
1414}
1415