xref: /aosp_15_r20/build/soong/java/java.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1// Copyright 2015 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
17// This file contains the module types for compiling Java for Android, and converts the properties
18// into the flags and filenames necessary to pass to the Module.  The final creation of the rules
19// is handled in builder.go
20
21import (
22	"fmt"
23	"path/filepath"
24	"slices"
25	"sort"
26	"strings"
27
28	"android/soong/remoteexec"
29
30	"github.com/google/blueprint"
31	"github.com/google/blueprint/depset"
32	"github.com/google/blueprint/proptools"
33
34	"android/soong/android"
35	"android/soong/cc"
36	"android/soong/dexpreopt"
37	"android/soong/java/config"
38	"android/soong/tradefed"
39)
40
41func init() {
42	registerJavaBuildComponents(android.InitRegistrationContext)
43
44	RegisterJavaSdkMemberTypes()
45}
46
47func registerJavaBuildComponents(ctx android.RegistrationContext) {
48	ctx.RegisterModuleType("java_defaults", DefaultsFactory)
49
50	ctx.RegisterModuleType("java_library", LibraryFactory)
51	ctx.RegisterModuleType("java_library_static", LibraryStaticFactory)
52	ctx.RegisterModuleType("java_library_host", LibraryHostFactory)
53	ctx.RegisterModuleType("java_binary", BinaryFactory)
54	ctx.RegisterModuleType("java_binary_host", BinaryHostFactory)
55	ctx.RegisterModuleType("java_test", TestFactory)
56	ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory)
57	ctx.RegisterModuleType("java_test_host", TestHostFactory)
58	ctx.RegisterModuleType("java_test_import", JavaTestImportFactory)
59	ctx.RegisterModuleType("java_import", ImportFactory)
60	ctx.RegisterModuleType("java_import_host", ImportFactoryHost)
61	ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory)
62	ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
63	ctx.RegisterModuleType("dex_import", DexImportFactory)
64	ctx.RegisterModuleType("java_api_library", ApiLibraryFactory)
65	ctx.RegisterModuleType("java_api_contribution", ApiContributionFactory)
66	ctx.RegisterModuleType("java_api_contribution_import", ApiContributionImportFactory)
67
68	// This mutator registers dependencies on dex2oat for modules that should be
69	// dexpreopted. This is done late when the final variants have been
70	// established, to not get the dependencies split into the wrong variants and
71	// to support the checks in dexpreoptDisabled().
72	ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
73		ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator)
74		// needs access to ApexInfoProvider which is available after variant creation
75		ctx.BottomUp("jacoco_deps", jacocoDepsMutator)
76	})
77
78	ctx.RegisterParallelSingletonType("kythe_java_extract", kytheExtractJavaFactory)
79}
80
81func RegisterJavaSdkMemberTypes() {
82	// Register sdk member types.
83	android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType)
84	android.RegisterSdkMemberType(javaLibsSdkMemberType)
85	android.RegisterSdkMemberType(JavaBootLibsSdkMemberType)
86	android.RegisterSdkMemberType(JavaSystemserverLibsSdkMemberType)
87	android.RegisterSdkMemberType(javaTestSdkMemberType)
88}
89
90type StubsLinkType int
91
92const (
93	Unknown StubsLinkType = iota
94	Stubs
95	Implementation
96)
97
98var (
99	// Supports adding java header libraries to module_exports and sdk.
100	javaHeaderLibsSdkMemberType = &librarySdkMemberType{
101		android.SdkMemberTypeBase{
102			PropertyName: "java_header_libs",
103			SupportsSdk:  true,
104		},
105		func(_ android.SdkMemberContext, j *Library) android.Path {
106			headerJars := j.HeaderJars()
107			if len(headerJars) != 1 {
108				panic(fmt.Errorf("there must be only one header jar from %q", j.Name()))
109			}
110
111			return headerJars[0]
112		},
113		sdkSnapshotFilePathForJar,
114		copyEverythingToSnapshot,
115	}
116
117	// Export implementation classes jar as part of the sdk.
118	exportImplementationClassesJar = func(_ android.SdkMemberContext, j *Library) android.Path {
119		implementationJars := j.ImplementationAndResourcesJars()
120		if len(implementationJars) != 1 {
121			panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name()))
122		}
123		return implementationJars[0]
124	}
125
126	// Supports adding java implementation libraries to module_exports but not sdk.
127	javaLibsSdkMemberType = &librarySdkMemberType{
128		android.SdkMemberTypeBase{
129			PropertyName: "java_libs",
130		},
131		exportImplementationClassesJar,
132		sdkSnapshotFilePathForJar,
133		copyEverythingToSnapshot,
134	}
135
136	snapshotRequiresImplementationJar = func(ctx android.SdkMemberContext) bool {
137		// In the S build the build will break if updatable-media does not provide a full implementation
138		// jar. That issue was fixed in Tiramisu by b/229932396.
139		if ctx.IsTargetBuildBeforeTiramisu() && ctx.Name() == "updatable-media" {
140			return true
141		}
142
143		return false
144	}
145
146	// Supports adding java boot libraries to module_exports and sdk.
147	//
148	// The build has some implicit dependencies (via the boot jars configuration) on a number of
149	// modules, e.g. core-oj, apache-xml, that are part of the java boot class path and which are
150	// provided by mainline modules (e.g. art, conscrypt, runtime-i18n) but which are not otherwise
151	// used outside those mainline modules.
152	//
153	// As they are not needed outside the mainline modules adding them to the sdk/module-exports as
154	// either java_libs, or java_header_libs would end up exporting more information than was strictly
155	// necessary. The java_boot_libs property to allow those modules to be exported as part of the
156	// sdk/module_exports without exposing any unnecessary information.
157	JavaBootLibsSdkMemberType = &librarySdkMemberType{
158		android.SdkMemberTypeBase{
159			PropertyName: "java_boot_libs",
160			SupportsSdk:  true,
161		},
162		func(ctx android.SdkMemberContext, j *Library) android.Path {
163			if snapshotRequiresImplementationJar(ctx) {
164				return exportImplementationClassesJar(ctx, j)
165			}
166
167			// Java boot libs are only provided in the SDK to provide access to their dex implementation
168			// jar for use by dexpreopting and boot jars package check. They do not need to provide an
169			// actual implementation jar but the java_import will need a file that exists so just copy an
170			// empty file. Any attempt to use that file as a jar will cause a build error.
171			return ctx.SnapshotBuilder().EmptyFile()
172		},
173		func(ctx android.SdkMemberContext, osPrefix, name string) string {
174			if snapshotRequiresImplementationJar(ctx) {
175				return sdkSnapshotFilePathForJar(ctx, osPrefix, name)
176			}
177
178			// Create a special name for the implementation jar to try and provide some useful information
179			// to a developer that attempts to compile against this.
180			// TODO(b/175714559): Provide a proper error message in Soong not ninja.
181			return filepath.Join(osPrefix, "java_boot_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix)
182		},
183		onlyCopyJarToSnapshot,
184	}
185
186	// Supports adding java systemserver libraries to module_exports and sdk.
187	//
188	// The build has some implicit dependencies (via the systemserver jars configuration) on a number
189	// of modules that are part of the java systemserver classpath and which are provided by mainline
190	// modules but which are not otherwise used outside those mainline modules.
191	//
192	// As they are not needed outside the mainline modules adding them to the sdk/module-exports as
193	// either java_libs, or java_header_libs would end up exporting more information than was strictly
194	// necessary. The java_systemserver_libs property to allow those modules to be exported as part of
195	// the sdk/module_exports without exposing any unnecessary information.
196	JavaSystemserverLibsSdkMemberType = &librarySdkMemberType{
197		android.SdkMemberTypeBase{
198			PropertyName: "java_systemserver_libs",
199			SupportsSdk:  true,
200
201			// This was only added in Tiramisu.
202			SupportedBuildReleaseSpecification: "Tiramisu+",
203		},
204		func(ctx android.SdkMemberContext, j *Library) android.Path {
205			// Java systemserver libs are only provided in the SDK to provide access to their dex
206			// implementation jar for use by dexpreopting. They do not need to provide an actual
207			// implementation jar but the java_import will need a file that exists so just copy an empty
208			// file. Any attempt to use that file as a jar will cause a build error.
209			return ctx.SnapshotBuilder().EmptyFile()
210		},
211		func(_ android.SdkMemberContext, osPrefix, name string) string {
212			// Create a special name for the implementation jar to try and provide some useful information
213			// to a developer that attempts to compile against this.
214			// TODO(b/175714559): Provide a proper error message in Soong not ninja.
215			return filepath.Join(osPrefix, "java_systemserver_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix)
216		},
217		onlyCopyJarToSnapshot,
218	}
219
220	// Supports adding java test libraries to module_exports but not sdk.
221	javaTestSdkMemberType = &testSdkMemberType{
222		SdkMemberTypeBase: android.SdkMemberTypeBase{
223			PropertyName: "java_tests",
224		},
225	}
226
227	// Rule for generating device binary default wrapper
228	deviceBinaryWrapper = pctx.StaticRule("deviceBinaryWrapper", blueprint.RuleParams{
229		Command: `printf '#!/system/bin/sh\n` +
230			`export CLASSPATH=/system/framework/$jar_name\n` +
231			`exec app_process /$partition/bin $main_class "$$@"\n'> ${out}`,
232		Description: "Generating device binary wrapper ${jar_name}",
233	}, "jar_name", "partition", "main_class")
234)
235
236type ProguardSpecInfo struct {
237	// If true, proguard flags files will be exported to reverse dependencies across libs edges
238	// If false, proguard flags files will only be exported to reverse dependencies across
239	// static_libs edges.
240	Export_proguard_flags_files bool
241
242	// TransitiveDepsProguardSpecFiles is a depset of paths to proguard flags files that are exported from
243	// all transitive deps. This list includes all proguard flags files from transitive static dependencies,
244	// and all proguard flags files from transitive libs dependencies which set `export_proguard_spec: true`.
245	ProguardFlagsFiles depset.DepSet[android.Path]
246
247	// implementation detail to store transitive proguard flags files from exporting shared deps
248	UnconditionallyExportedProguardFlags depset.DepSet[android.Path]
249}
250
251var ProguardSpecInfoProvider = blueprint.NewProvider[ProguardSpecInfo]()
252
253// JavaInfo contains information about a java module for use by modules that depend on it.
254type JavaInfo struct {
255	// HeaderJars is a list of jars that can be passed as the javac classpath in order to link
256	// against this module.  If empty, ImplementationJars should be used instead.
257	// Unlike LocalHeaderJars, HeaderJars includes classes from static dependencies.
258	HeaderJars android.Paths
259
260	RepackagedHeaderJars android.Paths
261
262	// set of header jars for all transitive libs deps
263	TransitiveLibsHeaderJarsForR8 depset.DepSet[android.Path]
264
265	// set of header jars for all transitive static libs deps
266	TransitiveStaticLibsHeaderJarsForR8 depset.DepSet[android.Path]
267
268	// depset of header jars for this module and all transitive static dependencies
269	TransitiveStaticLibsHeaderJars depset.DepSet[android.Path]
270
271	// depset of implementation jars for this module and all transitive static dependencies
272	TransitiveStaticLibsImplementationJars depset.DepSet[android.Path]
273
274	// depset of resource jars for this module and all transitive static dependencies
275	TransitiveStaticLibsResourceJars depset.DepSet[android.Path]
276
277	// ImplementationAndResourceJars is a list of jars that contain the implementations of classes
278	// in the module as well as any resources included in the module.
279	ImplementationAndResourcesJars android.Paths
280
281	// ImplementationJars is a list of jars that contain the implementations of classes in the
282	// module.
283	ImplementationJars android.Paths
284
285	// ResourceJars is a list of jars that contain the resources included in the module.
286	ResourceJars android.Paths
287
288	// LocalHeaderJars is a list of jars that contain classes from this module, but not from any static dependencies.
289	LocalHeaderJars android.Paths
290
291	// AidlIncludeDirs is a list of directories that should be passed to the aidl tool when
292	// depending on this module.
293	AidlIncludeDirs android.Paths
294
295	// SrcJarArgs is a list of arguments to pass to soong_zip to package the sources of this
296	// module.
297	SrcJarArgs []string
298
299	// SrcJarDeps is a list of paths to depend on when packaging the sources of this module.
300	SrcJarDeps android.Paths
301
302	// The source files of this module and all its transitive static dependencies.
303	TransitiveSrcFiles depset.DepSet[android.Path]
304
305	// ExportedPlugins is a list of paths that should be used as annotation processors for any
306	// module that depends on this module.
307	ExportedPlugins android.Paths
308
309	// ExportedPluginClasses is a list of classes that should be run as annotation processors for
310	// any module that depends on this module.
311	ExportedPluginClasses []string
312
313	// ExportedPluginDisableTurbine is true if this module's annotation processors generate APIs,
314	// requiring disbling turbine for any modules that depend on it.
315	ExportedPluginDisableTurbine bool
316
317	// JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be
318	// instrumented by jacoco.
319	JacocoReportClassesFile android.Path
320
321	// StubsLinkType provides information about whether the provided jars are stub jars or
322	// implementation jars. If the provider is set by java_sdk_library, the link type is "unknown"
323	// and selection between the stub jar vs implementation jar is deferred to SdkLibrary.sdkJars(...)
324	StubsLinkType StubsLinkType
325
326	// AconfigIntermediateCacheOutputPaths is a path to the cache files collected from the
327	// java_aconfig_library modules that are statically linked to this module.
328	AconfigIntermediateCacheOutputPaths android.Paths
329
330	SdkVersion android.SdkSpec
331}
332
333var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]()
334
335// SyspropPublicStubInfo contains info about the sysprop public stub library that corresponds to
336// the sysprop implementation library.
337type SyspropPublicStubInfo struct {
338	// JavaInfo is the JavaInfoProvider of the sysprop public stub library that corresponds to
339	// the sysprop implementation library.
340	JavaInfo *JavaInfo
341}
342
343var SyspropPublicStubInfoProvider = blueprint.NewProvider[SyspropPublicStubInfo]()
344
345// Methods that need to be implemented for a module that is added to apex java_libs property.
346type ApexDependency interface {
347	HeaderJars() android.Paths
348	ImplementationAndResourcesJars() android.Paths
349}
350
351// Provides build path and install path to DEX jars.
352type UsesLibraryDependency interface {
353	DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath
354	DexJarInstallPath() android.Path
355	ClassLoaderContexts() dexpreopt.ClassLoaderContextMap
356}
357
358// TODO(jungjw): Move this to kythe.go once it's created.
359type xref interface {
360	XrefJavaFiles() android.Paths
361	XrefKotlinFiles() android.Paths
362}
363
364func (j *Module) XrefJavaFiles() android.Paths {
365	return j.kytheFiles
366}
367
368func (j *Module) XrefKotlinFiles() android.Paths {
369	return j.kytheKotlinFiles
370}
371
372func (d dependencyTag) PropagateAconfigValidation() bool {
373	return d.static
374}
375
376var _ android.PropagateAconfigValidationDependencyTag = dependencyTag{}
377
378type dependencyTag struct {
379	blueprint.BaseDependencyTag
380	name string
381
382	// True if the dependency is relinked at runtime.
383	runtimeLinked bool
384
385	// True if the dependency is a toolchain, for example an annotation processor.
386	toolchain bool
387
388	static bool
389
390	installable bool
391}
392
393var _ android.InstallNeededDependencyTag = (*dependencyTag)(nil)
394
395func (d dependencyTag) InstallDepNeeded() bool {
396	return d.installable
397}
398
399func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation {
400	if d.runtimeLinked {
401		return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency}
402	} else if d.toolchain {
403		return []android.LicenseAnnotation{android.LicenseAnnotationToolchain}
404	}
405	return nil
406}
407
408var _ android.LicenseAnnotationsDependencyTag = dependencyTag{}
409
410type usesLibraryDependencyTag struct {
411	dependencyTag
412	sdkVersion int  // SDK version in which the library appared as a standalone library.
413	optional   bool // If the dependency is optional or required.
414}
415
416func makeUsesLibraryDependencyTag(sdkVersion int, optional bool) usesLibraryDependencyTag {
417	return usesLibraryDependencyTag{
418		dependencyTag: dependencyTag{
419			name:          fmt.Sprintf("uses-library-%d", sdkVersion),
420			runtimeLinked: true,
421		},
422		sdkVersion: sdkVersion,
423		optional:   optional,
424	}
425}
426
427func IsJniDepTag(depTag blueprint.DependencyTag) bool {
428	return depTag == jniLibTag || depTag == jniInstallTag
429}
430
431var (
432	dataNativeBinsTag       = dependencyTag{name: "dataNativeBins"}
433	dataDeviceBinsTag       = dependencyTag{name: "dataDeviceBins"}
434	staticLibTag            = dependencyTag{name: "staticlib", static: true}
435	libTag                  = dependencyTag{name: "javalib", runtimeLinked: true}
436	sdkLibTag               = dependencyTag{name: "sdklib", runtimeLinked: true}
437	java9LibTag             = dependencyTag{name: "java9lib", runtimeLinked: true}
438	pluginTag               = dependencyTag{name: "plugin", toolchain: true}
439	errorpronePluginTag     = dependencyTag{name: "errorprone-plugin", toolchain: true}
440	exportedPluginTag       = dependencyTag{name: "exported-plugin", toolchain: true}
441	bootClasspathTag        = dependencyTag{name: "bootclasspath", runtimeLinked: true}
442	systemModulesTag        = dependencyTag{name: "system modules", runtimeLinked: true}
443	frameworkResTag         = dependencyTag{name: "framework-res"}
444	kotlinPluginTag         = dependencyTag{name: "kotlin-plugin", toolchain: true}
445	proguardRaiseTag        = dependencyTag{name: "proguard-raise"}
446	certificateTag          = dependencyTag{name: "certificate"}
447	instrumentationForTag   = dependencyTag{name: "instrumentation_for"}
448	extraLintCheckTag       = dependencyTag{name: "extra-lint-check", toolchain: true}
449	jniLibTag               = dependencyTag{name: "jnilib", runtimeLinked: true}
450	r8LibraryJarTag         = dependencyTag{name: "r8-libraryjar", runtimeLinked: true}
451	syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
452	javaApiContributionTag  = dependencyTag{name: "java-api-contribution"}
453	aconfigDeclarationTag   = dependencyTag{name: "aconfig-declaration"}
454	jniInstallTag           = dependencyTag{name: "jni install", runtimeLinked: true, installable: true}
455	usesLibReqTag           = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false)
456	usesLibOptTag           = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true)
457	usesLibCompat28OptTag   = makeUsesLibraryDependencyTag(28, true)
458	usesLibCompat29ReqTag   = makeUsesLibraryDependencyTag(29, false)
459	usesLibCompat30OptTag   = makeUsesLibraryDependencyTag(30, true)
460)
461
462// A list of tags for deps used for compiling a module.
463// Any dependency tags that modifies the following properties of `deps` in `Module.collectDeps` should be
464// added to this list:
465// - bootClasspath
466// - classpath
467// - java9Classpath
468// - systemModules
469// - kotlin deps...
470var (
471	compileDependencyTags = []blueprint.DependencyTag{
472		sdkLibTag,
473		libTag,
474		staticLibTag,
475		bootClasspathTag,
476		systemModulesTag,
477		java9LibTag,
478		kotlinPluginTag,
479		syspropPublicStubDepTag,
480		instrumentationForTag,
481	}
482)
483
484func IsLibDepTag(depTag blueprint.DependencyTag) bool {
485	return depTag == libTag || depTag == sdkLibTag
486}
487
488func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool {
489	return depTag == staticLibTag
490}
491
492type sdkDep struct {
493	useModule, useFiles, invalidVersion bool
494
495	// The modules that will be added to the bootclasspath when targeting 1.8 or lower
496	bootclasspath []string
497
498	// The default system modules to use. Will be an empty string if no system
499	// modules are to be used.
500	systemModules string
501
502	// The modules that will be added to the classpath regardless of the Java language level targeted
503	classpath []string
504
505	// The modules that will be added ot the classpath when targeting 1.9 or higher
506	// (normally these will be on the bootclasspath when targeting 1.8 or lower)
507	java9Classpath []string
508
509	frameworkResModule string
510
511	jars android.Paths
512	aidl android.OptionalPath
513
514	noStandardLibs, noFrameworksLibs bool
515}
516
517func (s sdkDep) hasStandardLibs() bool {
518	return !s.noStandardLibs
519}
520
521func (s sdkDep) hasFrameworkLibs() bool {
522	return !s.noStandardLibs && !s.noFrameworksLibs
523}
524
525type jniLib struct {
526	name           string
527	path           android.Path
528	target         android.Target
529	coverageFile   android.OptionalPath
530	unstrippedFile android.Path
531	partition      string
532	installPaths   android.InstallPaths
533}
534
535func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) {
536	sdkDep := decodeSdkDep(ctx, sdkContext)
537	if sdkDep.useModule {
538		ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
539		ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
540		ctx.AddVariationDependencies(nil, sdkLibTag, sdkDep.classpath...)
541		if d.effectiveOptimizeEnabled() && sdkDep.hasStandardLibs() {
542			ctx.AddVariationDependencies(nil, proguardRaiseTag,
543				config.LegacyCorePlatformBootclasspathLibraries...,
544			)
545		}
546		if d.effectiveOptimizeEnabled() && sdkDep.hasFrameworkLibs() {
547			ctx.AddVariationDependencies(nil, proguardRaiseTag, config.FrameworkLibraries...)
548		}
549	}
550	if sdkDep.systemModules != "" {
551		ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
552	}
553}
554
555type deps struct {
556	// bootClasspath is the list of jars that form the boot classpath (generally the java.* and
557	// android.* classes) for tools that still use it.  javac targeting 1.9 or higher uses
558	// systemModules and java9Classpath instead.
559	bootClasspath classpath
560
561	// classpath is the list of jars that form the classpath for javac and kotlinc rules.  It
562	// contains header jars for all static and non-static dependencies.
563	classpath classpath
564
565	// dexClasspath is the list of jars that form the classpath for d8 and r8 rules.  It contains
566	// header jars for all non-static dependencies.  Static dependencies have already been
567	// combined into the program jar.
568	dexClasspath classpath
569
570	// java9Classpath is the list of jars that will be added to the classpath when targeting
571	// 1.9 or higher.  It generally contains the android.* classes, while the java.* classes
572	// are provided by systemModules.
573	java9Classpath classpath
574
575	processorPath           classpath ``
576	errorProneProcessorPath classpath
577	processorClasses        []string
578	staticJars              android.Paths
579	staticHeaderJars        android.Paths
580	staticResourceJars      android.Paths
581	aidlIncludeDirs         android.Paths
582	srcs                    android.Paths
583	srcJars                 android.Paths
584	systemModules           *systemModules
585	aidlPreprocess          android.OptionalPath
586	kotlinPlugins           android.Paths
587	aconfigProtoFiles       android.Paths
588
589	disableTurbine bool
590
591	transitiveStaticLibsHeaderJars         []depset.DepSet[android.Path]
592	transitiveStaticLibsImplementationJars []depset.DepSet[android.Path]
593	transitiveStaticLibsResourceJars       []depset.DepSet[android.Path]
594}
595
596func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) {
597	for _, f := range dep.Srcs() {
598		if f.Ext() != ".jar" {
599			ctx.ModuleErrorf("genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency",
600				ctx.OtherModuleName(dep.(blueprint.Module)))
601		}
602	}
603}
604
605func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext android.SdkContext) javaVersion {
606	if javaVersion != "" {
607		return normalizeJavaVersion(ctx, javaVersion)
608	} else if ctx.Device() {
609		return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx))
610	} else if ctx.Config().TargetsJava21() {
611		// Build flag that controls whether Java 21 is used as the default
612		// target version, or Java 17.
613		return JAVA_VERSION_21
614	} else {
615		return JAVA_VERSION_17
616	}
617}
618
619// Java version for stubs generation
620func getStubsJavaVersion() javaVersion {
621	return JAVA_VERSION_8
622}
623
624type javaVersion int
625
626const (
627	JAVA_VERSION_UNSUPPORTED = 0
628	JAVA_VERSION_6           = 6
629	JAVA_VERSION_7           = 7
630	JAVA_VERSION_8           = 8
631	JAVA_VERSION_9           = 9
632	JAVA_VERSION_11          = 11
633	JAVA_VERSION_17          = 17
634	JAVA_VERSION_21          = 21
635)
636
637func (v javaVersion) String() string {
638	switch v {
639	case JAVA_VERSION_6:
640		// Java version 1.6 no longer supported, bumping to 1.8
641		return "1.8"
642	case JAVA_VERSION_7:
643		// Java version 1.7 no longer supported, bumping to 1.8
644		return "1.8"
645	case JAVA_VERSION_8:
646		return "1.8"
647	case JAVA_VERSION_9:
648		return "1.9"
649	case JAVA_VERSION_11:
650		return "11"
651	case JAVA_VERSION_17:
652		return "17"
653	case JAVA_VERSION_21:
654		return "21"
655	default:
656		return "unsupported"
657	}
658}
659
660func (v javaVersion) StringForKotlinc() string {
661	// $ ./external/kotlinc/bin/kotlinc -jvm-target foo
662	// error: unknown JVM target version: foo
663	// Supported versions: 1.8, 9, 10, 11, 12, 13, 14, 15, 16, 17
664	switch v {
665	case JAVA_VERSION_6:
666		return "1.8"
667	case JAVA_VERSION_7:
668		return "1.8"
669	case JAVA_VERSION_9:
670		return "9"
671	default:
672		return v.String()
673	}
674}
675
676// Returns true if javac targeting this version uses system modules instead of a bootclasspath.
677func (v javaVersion) usesJavaModules() bool {
678	return v >= 9
679}
680
681func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) javaVersion {
682	switch javaVersion {
683	case "1.6", "6":
684		// Java version 1.6 no longer supported, bumping to 1.8
685		return JAVA_VERSION_8
686	case "1.7", "7":
687		// Java version 1.7 no longer supported, bumping to 1.8
688		return JAVA_VERSION_8
689	case "1.8", "8":
690		return JAVA_VERSION_8
691	case "1.9", "9":
692		return JAVA_VERSION_9
693	case "11":
694		return JAVA_VERSION_11
695	case "17":
696		return JAVA_VERSION_17
697	case "21":
698		return JAVA_VERSION_21
699	case "10", "12", "13", "14", "15", "16":
700		ctx.PropertyErrorf("java_version", "Java language level %s is not supported", javaVersion)
701		return JAVA_VERSION_UNSUPPORTED
702	default:
703		ctx.PropertyErrorf("java_version", "Unrecognized Java language level")
704		return JAVA_VERSION_UNSUPPORTED
705	}
706}
707
708//
709// Java libraries (.jar file)
710//
711
712type Library struct {
713	Module
714
715	combinedExportedProguardFlagsFile android.Path
716
717	InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.InstallPaths)
718}
719
720var _ android.ApexModule = (*Library)(nil)
721
722func (j *Library) CheckDepsMinSdkVersion(ctx android.ModuleContext) {
723	CheckMinSdkVersion(ctx, j)
724}
725
726// Provides access to the list of permitted packages from apex boot jars.
727type PermittedPackagesForUpdatableBootJars interface {
728	PermittedPackagesForUpdatableBootJars() []string
729}
730
731var _ PermittedPackagesForUpdatableBootJars = (*Library)(nil)
732
733func (j *Library) PermittedPackagesForUpdatableBootJars() []string {
734	return j.properties.Permitted_packages
735}
736
737func shouldUncompressDex(ctx android.ModuleContext, libName string, dexpreopter *dexpreopter) bool {
738	// Store uncompressed (and aligned) any dex files from jars in APEXes.
739	if apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider); !apexInfo.IsForPlatform() {
740		return true
741	}
742
743	// Store uncompressed (and do not strip) dex files from boot class path jars.
744	if inList(ctx.ModuleName(), ctx.Config().BootJars()) {
745		return true
746	}
747
748	// Store uncompressed dex files that are preopted on /system or /system_other.
749	if !dexpreopter.dexpreoptDisabled(ctx, libName) {
750		return true
751	}
752
753	if ctx.Config().UncompressPrivAppDex() &&
754		inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()) {
755		return true
756	}
757
758	return false
759}
760
761// Sets `dexer.dexProperties.Uncompress_dex` to the proper value.
762func setUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter, dexer *dexer) {
763	if dexer.dexProperties.Uncompress_dex == nil {
764		// If the value was not force-set by the user, use reasonable default based on the module.
765		dexer.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), dexpreopter))
766	}
767}
768
769// list of java_library modules that set platform_apis: true
770// this property is a no-op for java_library
771// TODO (b/215379393): Remove this allowlist
772var (
773	aospPlatformApiAllowlist = map[string]bool{
774		"adservices-test-scenarios":                         true,
775		"aidl-cpp-java-test-interface-java":                 true,
776		"aidl-test-extras-java":                             true,
777		"aidl-test-interface-java":                          true,
778		"aidl-test-interface-permission-java":               true,
779		"aidl_test_java_client_permission":                  true,
780		"aidl_test_java_client_sdk1":                        true,
781		"aidl_test_java_client_sdk29":                       true,
782		"aidl_test_java_client":                             true,
783		"aidl_test_java_service_permission":                 true,
784		"aidl_test_java_service_sdk1":                       true,
785		"aidl_test_java_service_sdk29":                      true,
786		"aidl_test_java_service":                            true,
787		"aidl_test_loggable_interface-java":                 true,
788		"aidl_test_nonvintf_parcelable-V1-java":             true,
789		"aidl_test_nonvintf_parcelable-V2-java":             true,
790		"aidl_test_unstable_parcelable-java":                true,
791		"aidl_test_vintf_parcelable-V1-java":                true,
792		"aidl_test_vintf_parcelable-V2-java":                true,
793		"android.aidl.test.trunk-V1-java":                   true,
794		"android.aidl.test.trunk-V2-java":                   true,
795		"android.frameworks.location.altitude-V1-java":      true,
796		"android.frameworks.location.altitude-V2-java":      true,
797		"android.frameworks.stats-V1-java":                  true,
798		"android.frameworks.stats-V2-java":                  true,
799		"android.frameworks.stats-V3-java":                  true,
800		"android.hardware.authsecret-V1-java":               true,
801		"android.hardware.authsecret-V2-java":               true,
802		"android.hardware.biometrics.common-V1-java":        true,
803		"android.hardware.biometrics.common-V2-java":        true,
804		"android.hardware.biometrics.common-V3-java":        true,
805		"android.hardware.biometrics.common-V4-java":        true,
806		"android.hardware.biometrics.face-V1-java":          true,
807		"android.hardware.biometrics.face-V2-java":          true,
808		"android.hardware.biometrics.face-V3-java":          true,
809		"android.hardware.biometrics.face-V4-java":          true,
810		"android.hardware.biometrics.fingerprint-V1-java":   true,
811		"android.hardware.biometrics.fingerprint-V2-java":   true,
812		"android.hardware.biometrics.fingerprint-V3-java":   true,
813		"android.hardware.biometrics.fingerprint-V4-java":   true,
814		"android.hardware.bluetooth.lmp_event-V1-java":      true,
815		"android.hardware.confirmationui-V1-java":           true,
816		"android.hardware.confirmationui-V2-java":           true,
817		"android.hardware.gatekeeper-V1-java":               true,
818		"android.hardware.gatekeeper-V2-java":               true,
819		"android.hardware.gnss-V1-java":                     true,
820		"android.hardware.gnss-V2-java":                     true,
821		"android.hardware.gnss-V3-java":                     true,
822		"android.hardware.gnss-V4-java":                     true,
823		"android.hardware.graphics.common-V1-java":          true,
824		"android.hardware.graphics.common-V2-java":          true,
825		"android.hardware.graphics.common-V3-java":          true,
826		"android.hardware.graphics.common-V4-java":          true,
827		"android.hardware.graphics.common-V5-java":          true,
828		"android.hardware.identity-V1-java":                 true,
829		"android.hardware.identity-V2-java":                 true,
830		"android.hardware.identity-V3-java":                 true,
831		"android.hardware.identity-V4-java":                 true,
832		"android.hardware.identity-V5-java":                 true,
833		"android.hardware.identity-V6-java":                 true,
834		"android.hardware.keymaster-V1-java":                true,
835		"android.hardware.keymaster-V2-java":                true,
836		"android.hardware.keymaster-V3-java":                true,
837		"android.hardware.keymaster-V4-java":                true,
838		"android.hardware.keymaster-V5-java":                true,
839		"android.hardware.oemlock-V1-java":                  true,
840		"android.hardware.oemlock-V2-java":                  true,
841		"android.hardware.power.stats-V1-java":              true,
842		"android.hardware.power.stats-V2-java":              true,
843		"android.hardware.power.stats-V3-java":              true,
844		"android.hardware.power-V1-java":                    true,
845		"android.hardware.power-V2-java":                    true,
846		"android.hardware.power-V3-java":                    true,
847		"android.hardware.power-V4-java":                    true,
848		"android.hardware.power-V5-java":                    true,
849		"android.hardware.rebootescrow-V1-java":             true,
850		"android.hardware.rebootescrow-V2-java":             true,
851		"android.hardware.security.authgraph-V1-java":       true,
852		"android.hardware.security.keymint-V1-java":         true,
853		"android.hardware.security.keymint-V2-java":         true,
854		"android.hardware.security.keymint-V3-java":         true,
855		"android.hardware.security.keymint-V4-java":         true,
856		"android.hardware.security.secretkeeper-V1-java":    true,
857		"android.hardware.security.secureclock-V1-java":     true,
858		"android.hardware.security.secureclock-V2-java":     true,
859		"android.hardware.thermal-V1-java":                  true,
860		"android.hardware.thermal-V2-java":                  true,
861		"android.hardware.threadnetwork-V1-java":            true,
862		"android.hardware.weaver-V1-java":                   true,
863		"android.hardware.weaver-V2-java":                   true,
864		"android.hardware.weaver-V3-java":                   true,
865		"android.security.attestationmanager-java":          true,
866		"android.security.authorization-java":               true,
867		"android.security.compat-java":                      true,
868		"android.security.legacykeystore-java":              true,
869		"android.security.maintenance-java":                 true,
870		"android.security.metrics-java":                     true,
871		"android.system.keystore2-V1-java":                  true,
872		"android.system.keystore2-V2-java":                  true,
873		"android.system.keystore2-V3-java":                  true,
874		"android.system.keystore2-V4-java":                  true,
875		"binderReadParcelIface-java":                        true,
876		"binderRecordReplayTestIface-java":                  true,
877		"car-experimental-api-static-lib":                   true,
878		"collector-device-lib-platform":                     true,
879		"com.android.car.oem":                               true,
880		"com.google.hardware.pixel.display-V10-java":        true,
881		"com.google.hardware.pixel.display-V1-java":         true,
882		"com.google.hardware.pixel.display-V2-java":         true,
883		"com.google.hardware.pixel.display-V3-java":         true,
884		"com.google.hardware.pixel.display-V4-java":         true,
885		"com.google.hardware.pixel.display-V5-java":         true,
886		"com.google.hardware.pixel.display-V6-java":         true,
887		"com.google.hardware.pixel.display-V7-java":         true,
888		"com.google.hardware.pixel.display-V8-java":         true,
889		"com.google.hardware.pixel.display-V9-java":         true,
890		"conscrypt-support":                                 true,
891		"cts-keystore-test-util":                            true,
892		"cts-keystore-user-auth-helper-library":             true,
893		"ctsmediautil":                                      true,
894		"CtsNetTestsNonUpdatableLib":                        true,
895		"DpmWrapper":                                        true,
896		"flickerlib-apphelpers":                             true,
897		"flickerlib-helpers":                                true,
898		"flickerlib-parsers":                                true,
899		"flickerlib":                                        true,
900		"hardware.google.bluetooth.ccc-V1-java":             true,
901		"hardware.google.bluetooth.sar-V1-java":             true,
902		"monet":                                             true,
903		"pixel-power-ext-V1-java":                           true,
904		"pixel-power-ext-V2-java":                           true,
905		"pixel_stateresidency_provider_aidl_interface-java": true,
906		"pixel-thermal-ext-V1-java":                         true,
907		"protolog-lib":                                      true,
908		"RkpRegistrationCheck":                              true,
909		"rotary-service-javastream-protos":                  true,
910		"service_based_camera_extensions":                   true,
911		"statsd-helper-test":                                true,
912		"statsd-helper":                                     true,
913		"test-piece-2-V1-java":                              true,
914		"test-piece-2-V2-java":                              true,
915		"test-piece-3-V1-java":                              true,
916		"test-piece-3-V2-java":                              true,
917		"test-piece-3-V3-java":                              true,
918		"test-piece-4-V1-java":                              true,
919		"test-piece-4-V2-java":                              true,
920		"test-root-package-V1-java":                         true,
921		"test-root-package-V2-java":                         true,
922		"test-root-package-V3-java":                         true,
923		"test-root-package-V4-java":                         true,
924		"testServiceIface-java":                             true,
925		"wm-flicker-common-app-helpers":                     true,
926		"wm-flicker-common-assertions":                      true,
927		"wm-shell-flicker-utils":                            true,
928		"wycheproof-keystore":                               true,
929	}
930
931	// Union of aosp and internal allowlists
932	PlatformApiAllowlist = map[string]bool{}
933)
934
935func init() {
936	for k, v := range aospPlatformApiAllowlist {
937		PlatformApiAllowlist[k] = v
938	}
939}
940
941func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
942	if disableSourceApexVariant(ctx) {
943		// Prebuilts are active, do not create the installation rules for the source javalib.
944		// Even though the source javalib is not used, we need to hide it to prevent duplicate installation rules.
945		// TODO (b/331665856): Implement a principled solution for this.
946		j.HideFromMake()
947		j.SkipInstall()
948	}
949	j.provideHiddenAPIPropertyInfo(ctx)
950
951	j.sdkVersion = j.SdkVersion(ctx)
952	j.minSdkVersion = j.MinSdkVersion(ctx)
953	j.maxSdkVersion = j.MaxSdkVersion(ctx)
954
955	// Check min_sdk_version of the transitive dependencies if this module is created from
956	// java_sdk_library.
957	if j.overridableProperties.Min_sdk_version != nil && j.SdkLibraryName() != nil {
958		j.CheckDepsMinSdkVersion(ctx)
959	}
960
961	// SdkLibrary.GenerateAndroidBuildActions(ctx) sets the stubsLinkType to Unknown.
962	// If the stubsLinkType has already been set to Unknown, the stubsLinkType should
963	// not be overridden.
964	if j.stubsLinkType != Unknown {
965		if proptools.Bool(j.properties.Is_stubs_module) {
966			j.stubsLinkType = Stubs
967		} else {
968			j.stubsLinkType = Implementation
969		}
970	}
971
972	j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName())
973
974	proguardSpecInfo := j.collectProguardSpecInfo(ctx)
975	android.SetProvider(ctx, ProguardSpecInfoProvider, proguardSpecInfo)
976	exportedProguardFlagsFiles := proguardSpecInfo.ProguardFlagsFiles.ToList()
977	j.extraProguardFlagsFiles = append(j.extraProguardFlagsFiles, exportedProguardFlagsFiles...)
978
979	combinedExportedProguardFlagFile := android.PathForModuleOut(ctx, "export_proguard_flags")
980	writeCombinedProguardFlagsFile(ctx, combinedExportedProguardFlagFile, exportedProguardFlagsFiles)
981	j.combinedExportedProguardFlagsFile = combinedExportedProguardFlagFile
982
983	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
984	if !apexInfo.IsForPlatform() {
985		j.hideApexVariantFromMake = true
986	}
987
988	j.checkSdkVersions(ctx)
989	j.checkHeadersOnly(ctx)
990	if ctx.Device() {
991		libName := j.Name()
992		if j.SdkLibraryName() != nil && strings.HasSuffix(libName, ".impl") {
993			libName = proptools.String(j.SdkLibraryName())
994		}
995		j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
996			ctx, libName, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
997		j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
998		setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
999		j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
1000		j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
1001		if j.usesLibrary.shouldDisableDexpreopt {
1002			j.dexpreopter.disableDexpreopt()
1003		}
1004	}
1005	j.compile(ctx, nil, nil, nil, nil)
1006
1007	j.setInstallRules(ctx)
1008
1009	android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
1010		TestOnly:       Bool(j.sourceProperties.Test_only),
1011		TopLevelTarget: j.sourceProperties.Top_level_test_target,
1012	})
1013
1014	setOutputFiles(ctx, j.Module)
1015}
1016
1017func (j *Library) getJarInstallDir(ctx android.ModuleContext) android.InstallPath {
1018	var installDir android.InstallPath
1019	if ctx.InstallInTestcases() {
1020		var archDir string
1021		if !ctx.Host() {
1022			archDir = ctx.DeviceConfig().DeviceArch()
1023		}
1024		installModuleName := ctx.ModuleName()
1025		// If this module is an impl library created from java_sdk_library,
1026		// install the files under the java_sdk_library module outdir instead of this module outdir.
1027		if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") {
1028			installModuleName = proptools.String(j.SdkLibraryName())
1029		}
1030		installDir = android.PathForModuleInstall(ctx, installModuleName, archDir)
1031	} else {
1032		installDir = android.PathForModuleInstall(ctx, "framework")
1033	}
1034	return installDir
1035}
1036
1037func (j *Library) setInstallRules(ctx android.ModuleContext) {
1038	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
1039
1040	if (Bool(j.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() {
1041		var extraInstallDeps android.InstallPaths
1042		if j.InstallMixin != nil {
1043			extraInstallDeps = j.InstallMixin(ctx, j.outputFile)
1044		}
1045		hostDexNeeded := Bool(j.deviceProperties.Hostdex) && !ctx.Host()
1046		if hostDexNeeded {
1047			j.hostdexInstallFile = ctx.InstallFileWithoutCheckbuild(
1048				android.PathForHostDexInstall(ctx, "framework"),
1049				j.Stem()+"-hostdex.jar", j.outputFile)
1050		}
1051		j.installFile = ctx.InstallFileWithoutCheckbuild(j.getJarInstallDir(ctx), j.Stem()+".jar", j.outputFile, extraInstallDeps...)
1052	}
1053}
1054
1055func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
1056	j.usesLibrary.deps(ctx, false)
1057	j.deps(ctx)
1058
1059	if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") {
1060		if dexpreopt.IsDex2oatNeeded(ctx) {
1061			dexpreopt.RegisterToolDeps(ctx)
1062		}
1063		prebuiltSdkLibExists := ctx.OtherModuleExists(android.PrebuiltNameFromSource(proptools.String(j.SdkLibraryName())))
1064		if prebuiltSdkLibExists && ctx.OtherModuleExists("all_apex_contributions") {
1065			ctx.AddDependency(ctx.Module(), android.AcDepTag, "all_apex_contributions")
1066		}
1067	}
1068}
1069
1070const (
1071	aidlIncludeDir   = "aidl"
1072	javaDir          = "java"
1073	jarFileSuffix    = ".jar"
1074	testConfigSuffix = "-AndroidTest.xml"
1075)
1076
1077// path to the jar file of a java library. Relative to <sdk_root>/<api_dir>
1078func sdkSnapshotFilePathForJar(_ android.SdkMemberContext, osPrefix, name string) string {
1079	return sdkSnapshotFilePathForMember(osPrefix, name, jarFileSuffix)
1080}
1081
1082func sdkSnapshotFilePathForMember(osPrefix, name string, suffix string) string {
1083	return filepath.Join(javaDir, osPrefix, name+suffix)
1084}
1085
1086type librarySdkMemberType struct {
1087	android.SdkMemberTypeBase
1088
1089	// Function to retrieve the appropriate output jar (implementation or header) from
1090	// the library.
1091	jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path
1092
1093	// Function to compute the snapshot relative path to which the named library's
1094	// jar should be copied.
1095	snapshotPathGetter func(ctx android.SdkMemberContext, osPrefix, name string) string
1096
1097	// True if only the jar should be copied to the snapshot, false if the jar plus any additional
1098	// files like aidl files should also be copied.
1099	onlyCopyJarToSnapshot bool
1100}
1101
1102const (
1103	onlyCopyJarToSnapshot    = true
1104	copyEverythingToSnapshot = false
1105)
1106
1107func (mt *librarySdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) {
1108	ctx.AddVariationDependencies(nil, dependencyTag, names...)
1109}
1110
1111func (mt *librarySdkMemberType) IsInstance(module android.Module) bool {
1112	_, ok := module.(*Library)
1113	return ok
1114}
1115
1116func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
1117	return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_import")
1118}
1119
1120func (mt *librarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
1121	return &librarySdkMemberProperties{}
1122}
1123
1124type librarySdkMemberProperties struct {
1125	android.SdkMemberPropertiesBase
1126
1127	JarToExport     android.Path `android:"arch_variant"`
1128	AidlIncludeDirs android.Paths
1129
1130	// The list of permitted packages that need to be passed to the prebuilts as they are used to
1131	// create the updatable-bcp-packages.txt file.
1132	PermittedPackages []string
1133
1134	// The value of the min_sdk_version property, translated into a number where possible.
1135	MinSdkVersion *string `supported_build_releases:"Tiramisu+"`
1136
1137	DexPreoptProfileGuided *bool `supported_build_releases:"UpsideDownCake+"`
1138}
1139
1140func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
1141	j := variant.(*Library)
1142
1143	p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j)
1144
1145	p.AidlIncludeDirs = j.AidlIncludeDirs()
1146
1147	p.PermittedPackages = j.PermittedPackagesForUpdatableBootJars()
1148
1149	// If the min_sdk_version was set then add the canonical representation of the API level to the
1150	// snapshot.
1151	if j.overridableProperties.Min_sdk_version != nil {
1152		canonical, err := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.String())
1153		if err != nil {
1154			ctx.ModuleErrorf("%s", err)
1155		}
1156		p.MinSdkVersion = proptools.StringPtr(canonical)
1157	}
1158
1159	if j.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided {
1160		p.DexPreoptProfileGuided = proptools.BoolPtr(true)
1161	}
1162}
1163
1164func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
1165	builder := ctx.SnapshotBuilder()
1166
1167	memberType := ctx.MemberType().(*librarySdkMemberType)
1168
1169	exportedJar := p.JarToExport
1170	if exportedJar != nil {
1171		// Delegate the creation of the snapshot relative path to the member type.
1172		snapshotRelativeJavaLibPath := memberType.snapshotPathGetter(ctx, p.OsPrefix(), ctx.Name())
1173
1174		// Copy the exported jar to the snapshot.
1175		builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath)
1176
1177		propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
1178	}
1179
1180	if p.MinSdkVersion != nil {
1181		propertySet.AddProperty("min_sdk_version", *p.MinSdkVersion)
1182	}
1183
1184	if len(p.PermittedPackages) > 0 {
1185		propertySet.AddProperty("permitted_packages", p.PermittedPackages)
1186	}
1187
1188	dexPreoptSet := propertySet.AddPropertySet("dex_preopt")
1189	if p.DexPreoptProfileGuided != nil {
1190		dexPreoptSet.AddProperty("profile_guided", proptools.Bool(p.DexPreoptProfileGuided))
1191	}
1192
1193	// Do not copy anything else to the snapshot.
1194	if memberType.onlyCopyJarToSnapshot {
1195		return
1196	}
1197
1198	aidlIncludeDirs := p.AidlIncludeDirs
1199	if len(aidlIncludeDirs) != 0 {
1200		sdkModuleContext := ctx.SdkModuleContext()
1201		for _, dir := range aidlIncludeDirs {
1202			// TODO(jiyong): copy parcelable declarations only
1203			aidlFiles, _ := sdkModuleContext.GlobWithDeps(dir.String()+"/**/*.aidl", nil)
1204			for _, file := range aidlFiles {
1205				builder.CopyToSnapshot(android.PathForSource(sdkModuleContext, file), filepath.Join(aidlIncludeDir, file))
1206			}
1207		}
1208
1209		// TODO(b/151933053) - add aidl include dirs property
1210	}
1211}
1212
1213// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well.
1214//
1215// By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were
1216// compiled against the device bootclasspath.  This jar is not suitable for installing on a device, but can be used
1217// as a `static_libs` dependency of another module.
1218//
1219// Specifying `installable: true` will product a `.jar` file containing `classes.dex` files, suitable for installing on
1220// a device.
1221//
1222// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
1223// compiled against the host bootclasspath.
1224func LibraryFactory() android.Module {
1225	module := &Library{}
1226
1227	module.addHostAndDeviceProperties()
1228	module.AddProperties(&module.sourceProperties)
1229
1230	module.initModuleAndImport(module)
1231
1232	android.InitApexModule(module)
1233	InitJavaModule(module, android.HostAndDeviceSupported)
1234	return module
1235}
1236
1237// java_library_static is an obsolete alias for java_library.
1238func LibraryStaticFactory() android.Module {
1239	return LibraryFactory()
1240}
1241
1242// java_library_host builds and links sources into a `.jar` file for the host.
1243//
1244// A java_library_host has a single variant that produces a `.jar` file containing `.class` files that were
1245// compiled against the host bootclasspath.
1246func LibraryHostFactory() android.Module {
1247	module := &Library{}
1248
1249	module.addHostProperties()
1250
1251	module.Module.properties.Installable = proptools.BoolPtr(true)
1252
1253	android.InitApexModule(module)
1254	InitJavaModule(module, android.HostSupported)
1255	return module
1256}
1257
1258//
1259// Java Tests
1260//
1261
1262// Test option struct.
1263type TestOptions struct {
1264	android.CommonTestOptions
1265
1266	// a list of extra test configuration files that should be installed with the module.
1267	Extra_test_configs []string `android:"path,arch_variant"`
1268
1269	// Extra <option> tags to add to the auto generated test xml file. The "key"
1270	// is optional in each of these.
1271	Tradefed_options []tradefed.Option
1272
1273	// Extra <option> tags to add to the auto generated test xml file under the test runner, e.g., AndroidJunitTest.
1274	// The "key" is optional in each of these.
1275	Test_runner_options []tradefed.Option
1276}
1277
1278type testProperties struct {
1279	// list of compatibility suites (for example "cts", "vts") that the module should be
1280	// installed into.
1281	Test_suites []string `android:"arch_variant"`
1282
1283	// the name of the test configuration (for example "AndroidTest.xml") that should be
1284	// installed with the module.
1285	Test_config *string `android:"path,arch_variant"`
1286
1287	// the name of the test configuration template (for example "AndroidTestTemplate.xml") that
1288	// should be installed with the module.
1289	Test_config_template *string `android:"path,arch_variant"`
1290
1291	// list of files or filegroup modules that provide data that should be installed alongside
1292	// the test
1293	Data []string `android:"path"`
1294
1295	// Same as data, but will add dependencies on modules using the device's os variation and
1296	// the common arch variation. Useful for a host test that wants to embed a module built for
1297	// device.
1298	Device_common_data []string `android:"path_device_common"`
1299
1300	// same as data, but adds dependencies using the device's os variation and the device's first
1301	// architecture's variation. Can be used to add a module built for device to the data of a
1302	// host test.
1303	Device_first_data []string `android:"path_device_first"`
1304
1305	// same as data, but adds dependencies using the device's os variation and the device's first
1306	// 32-bit architecture's variation. If a 32-bit arch doesn't exist for this device, it will use
1307	// a 64 bit arch instead. Can be used to add a module built for device to the data of a
1308	// host test.
1309	Device_first_prefer32_data []string `android:"path_device_first_prefer32"`
1310
1311	// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
1312	// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
1313	// explicitly.
1314	Auto_gen_config *bool
1315
1316	// Add parameterized mainline modules to auto generated test config. The options will be
1317	// handled by TradeFed to do downloading and installing the specified modules on the device.
1318	Test_mainline_modules []string
1319
1320	// Test options.
1321	Test_options TestOptions
1322
1323	// Names of modules containing JNI libraries that should be installed alongside the test.
1324	Jni_libs proptools.Configurable[[]string]
1325
1326	// Install the test into a folder named for the module in all test suites.
1327	Per_testcase_directory *bool
1328}
1329
1330type hostTestProperties struct {
1331	// list of native binary modules that should be installed alongside the test
1332	Data_native_bins []string `android:"arch_variant"`
1333
1334	// list of device binary modules that should be installed alongside the test
1335	// This property only adds the first variant of the dependency
1336	Data_device_bins_first []string `android:"arch_variant"`
1337
1338	// list of device binary modules that should be installed alongside the test
1339	// This property adds 64bit AND 32bit variants of the dependency
1340	Data_device_bins_both []string `android:"arch_variant"`
1341
1342	// list of device binary modules that should be installed alongside the test
1343	// This property only adds 64bit variants of the dependency
1344	Data_device_bins_64 []string `android:"arch_variant"`
1345
1346	// list of device binary modules that should be installed alongside the test
1347	// This property adds 32bit variants of the dependency if available, or else
1348	// defaults to the 64bit variant
1349	Data_device_bins_prefer32 []string `android:"arch_variant"`
1350
1351	// list of device binary modules that should be installed alongside the test
1352	// This property only adds 32bit variants of the dependency
1353	Data_device_bins_32 []string `android:"arch_variant"`
1354}
1355
1356type testHelperLibraryProperties struct {
1357	// list of compatibility suites (for example "cts", "vts") that the module should be
1358	// installed into.
1359	Test_suites []string `android:"arch_variant"`
1360
1361	// Install the test into a folder named for the module in all test suites.
1362	Per_testcase_directory *bool
1363}
1364
1365type prebuiltTestProperties struct {
1366	// list of compatibility suites (for example "cts", "vts") that the module should be
1367	// installed into.
1368	Test_suites []string `android:"arch_variant"`
1369
1370	// the name of the test configuration (for example "AndroidTest.xml") that should be
1371	// installed with the module.
1372	Test_config *string `android:"path,arch_variant"`
1373}
1374
1375type Test struct {
1376	Library
1377
1378	testProperties testProperties
1379
1380	testConfig       android.Path
1381	extraTestConfigs android.Paths
1382	data             android.Paths
1383}
1384
1385type TestHost struct {
1386	Test
1387
1388	testHostProperties hostTestProperties
1389}
1390
1391type TestHelperLibrary struct {
1392	Library
1393
1394	testHelperLibraryProperties testHelperLibraryProperties
1395}
1396
1397type JavaTestImport struct {
1398	Import
1399
1400	prebuiltTestProperties prebuiltTestProperties
1401
1402	testConfig android.Path
1403	dexJarFile android.Path
1404}
1405
1406func (j *Test) InstallInTestcases() bool {
1407	// Host java tests install into $(HOST_OUT_JAVA_LIBRARIES), and then are copied into
1408	// testcases by base_rules.mk.
1409	return !j.Host()
1410}
1411
1412func (j *TestHelperLibrary) InstallInTestcases() bool {
1413	return true
1414}
1415
1416func (j *JavaTestImport) InstallInTestcases() bool {
1417	return true
1418}
1419
1420func (j *TestHost) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
1421	return ctx.DeviceConfig().NativeCoverageEnabled()
1422}
1423
1424func (j *TestHost) addDataDeviceBinsDeps(ctx android.BottomUpMutatorContext) {
1425	if len(j.testHostProperties.Data_device_bins_first) > 0 {
1426		deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations()
1427		ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_first...)
1428	}
1429
1430	var maybeAndroid32Target *android.Target
1431	var maybeAndroid64Target *android.Target
1432	android32TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib32")
1433	android64TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib64")
1434	if len(android32TargetList) > 0 {
1435		maybeAndroid32Target = &android32TargetList[0]
1436	}
1437	if len(android64TargetList) > 0 {
1438		maybeAndroid64Target = &android64TargetList[0]
1439	}
1440
1441	if len(j.testHostProperties.Data_device_bins_both) > 0 {
1442		if maybeAndroid32Target == nil && maybeAndroid64Target == nil {
1443			ctx.PropertyErrorf("data_device_bins_both", "no device targets available. Targets: %q", ctx.Config().Targets)
1444			return
1445		}
1446		if maybeAndroid32Target != nil {
1447			ctx.AddFarVariationDependencies(
1448				maybeAndroid32Target.Variations(),
1449				dataDeviceBinsTag,
1450				j.testHostProperties.Data_device_bins_both...,
1451			)
1452		}
1453		if maybeAndroid64Target != nil {
1454			ctx.AddFarVariationDependencies(
1455				maybeAndroid64Target.Variations(),
1456				dataDeviceBinsTag,
1457				j.testHostProperties.Data_device_bins_both...,
1458			)
1459		}
1460	}
1461
1462	if len(j.testHostProperties.Data_device_bins_prefer32) > 0 {
1463		if maybeAndroid32Target != nil {
1464			ctx.AddFarVariationDependencies(
1465				maybeAndroid32Target.Variations(),
1466				dataDeviceBinsTag,
1467				j.testHostProperties.Data_device_bins_prefer32...,
1468			)
1469		} else {
1470			if maybeAndroid64Target == nil {
1471				ctx.PropertyErrorf("data_device_bins_prefer32", "no device targets available. Targets: %q", ctx.Config().Targets)
1472				return
1473			}
1474			ctx.AddFarVariationDependencies(
1475				maybeAndroid64Target.Variations(),
1476				dataDeviceBinsTag,
1477				j.testHostProperties.Data_device_bins_prefer32...,
1478			)
1479		}
1480	}
1481
1482	if len(j.testHostProperties.Data_device_bins_32) > 0 {
1483		if maybeAndroid32Target == nil {
1484			ctx.PropertyErrorf("data_device_bins_32", "cannot find 32bit device target. Targets: %q", ctx.Config().Targets)
1485			return
1486		}
1487		deviceVariations := maybeAndroid32Target.Variations()
1488		ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_32...)
1489	}
1490
1491	if len(j.testHostProperties.Data_device_bins_64) > 0 {
1492		if maybeAndroid64Target == nil {
1493			ctx.PropertyErrorf("data_device_bins_64", "cannot find 64bit device target. Targets: %q", ctx.Config().Targets)
1494			return
1495		}
1496		deviceVariations := maybeAndroid64Target.Variations()
1497		ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_64...)
1498	}
1499}
1500
1501func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) {
1502	if len(j.testHostProperties.Data_native_bins) > 0 {
1503		for _, target := range ctx.MultiTargets() {
1504			ctx.AddVariationDependencies(target.Variations(), dataNativeBinsTag, j.testHostProperties.Data_native_bins...)
1505		}
1506	}
1507
1508	jniLibs := j.testProperties.Jni_libs.GetOrDefault(ctx, nil)
1509	if len(jniLibs) > 0 {
1510		for _, target := range ctx.MultiTargets() {
1511			sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
1512			ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, jniLibs...)
1513		}
1514	}
1515
1516	j.addDataDeviceBinsDeps(ctx)
1517	j.deps(ctx)
1518}
1519
1520func (j *TestHost) AddExtraResource(p android.Path) {
1521	j.extraResources = append(j.extraResources, p)
1522}
1523
1524func (j *TestHost) dataDeviceBins() []string {
1525	ret := make([]string, 0,
1526		len(j.testHostProperties.Data_device_bins_first)+
1527			len(j.testHostProperties.Data_device_bins_both)+
1528			len(j.testHostProperties.Data_device_bins_prefer32)+
1529			len(j.testHostProperties.Data_device_bins_32)+
1530			len(j.testHostProperties.Data_device_bins_64),
1531	)
1532
1533	ret = append(ret, j.testHostProperties.Data_device_bins_first...)
1534	ret = append(ret, j.testHostProperties.Data_device_bins_both...)
1535	ret = append(ret, j.testHostProperties.Data_device_bins_prefer32...)
1536	ret = append(ret, j.testHostProperties.Data_device_bins_32...)
1537	ret = append(ret, j.testHostProperties.Data_device_bins_64...)
1538
1539	return ret
1540}
1541
1542func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1543	var configs []tradefed.Config
1544	dataDeviceBins := j.dataDeviceBins()
1545	if len(dataDeviceBins) > 0 {
1546		// add Tradefed configuration to push device bins to device for testing
1547		remoteDir := filepath.Join("/data/local/tests/unrestricted/", j.Name())
1548		options := []tradefed.Option{{Name: "cleanup", Value: "true"}}
1549		for _, bin := range dataDeviceBins {
1550			fullPath := filepath.Join(remoteDir, bin)
1551			options = append(options, tradefed.Option{Name: "push-file", Key: bin, Value: fullPath})
1552		}
1553		configs = append(configs, tradefed.Object{
1554			Type:    "target_preparer",
1555			Class:   "com.android.tradefed.targetprep.PushFilePreparer",
1556			Options: options,
1557		})
1558	}
1559
1560	j.Test.generateAndroidBuildActionsWithConfig(ctx, configs)
1561	android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
1562		TestcaseRelDataFiles: testcaseRel(j.data),
1563		OutputFile:           j.outputFile,
1564		TestConfig:           j.testConfig,
1565		RequiredModuleNames:  j.RequiredModuleNames(ctx),
1566		TestSuites:           j.testProperties.Test_suites,
1567		IsHost:               true,
1568		LocalSdkVersion:      j.sdkVersion.String(),
1569		IsUnitTest:           Bool(j.testProperties.Test_options.Unit_test),
1570		MkInclude:            "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
1571		MkAppClass:           "JAVA_LIBRARIES",
1572	})
1573}
1574
1575func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1576	checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx))
1577	j.generateAndroidBuildActionsWithConfig(ctx, nil)
1578}
1579
1580func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, configs []tradefed.Config) {
1581	if j.testProperties.Test_options.Unit_test == nil && ctx.Host() {
1582		// TODO(b/): Clean temporary heuristic to avoid unexpected onboarding.
1583		defaultUnitTest := !inList("tradefed", j.properties.Libs) && !inList("cts", j.testProperties.Test_suites)
1584		j.testProperties.Test_options.Unit_test = proptools.BoolPtr(defaultUnitTest)
1585	}
1586	j.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
1587		TestConfigProp:          j.testProperties.Test_config,
1588		TestConfigTemplateProp:  j.testProperties.Test_config_template,
1589		TestSuites:              j.testProperties.Test_suites,
1590		Config:                  configs,
1591		OptionsForAutogenerated: j.testProperties.Test_options.Tradefed_options,
1592		TestRunnerOptions:       j.testProperties.Test_options.Test_runner_options,
1593		AutoGenConfig:           j.testProperties.Auto_gen_config,
1594		UnitTest:                j.testProperties.Test_options.Unit_test,
1595		DeviceTemplate:          "${JavaTestConfigTemplate}",
1596		HostTemplate:            "${JavaHostTestConfigTemplate}",
1597		HostUnitTestTemplate:    "${JavaHostUnitTestConfigTemplate}",
1598	})
1599
1600	j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
1601	j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_common_data)...)
1602	j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_first_data)...)
1603	j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_first_prefer32_data)...)
1604
1605	j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs)
1606
1607	ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) {
1608		j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
1609	})
1610
1611	ctx.VisitDirectDepsWithTag(dataDeviceBinsTag, func(dep android.Module) {
1612		j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
1613	})
1614
1615	var directImplementationDeps android.Paths
1616	var transitiveImplementationDeps []depset.DepSet[android.Path]
1617	ctx.VisitDirectDepsWithTag(jniLibTag, func(dep android.Module) {
1618		sharedLibInfo, _ := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider)
1619		if sharedLibInfo.SharedLibrary != nil {
1620			// Copy to an intermediate output directory to append "lib[64]" to the path,
1621			// so that it's compatible with the default rpath values.
1622			var relPath string
1623			if sharedLibInfo.Target.Arch.ArchType.Multilib == "lib64" {
1624				relPath = filepath.Join("lib64", sharedLibInfo.SharedLibrary.Base())
1625			} else {
1626				relPath = filepath.Join("lib", sharedLibInfo.SharedLibrary.Base())
1627			}
1628			relocatedLib := android.PathForModuleOut(ctx, "relocated").Join(ctx, relPath)
1629			ctx.Build(pctx, android.BuildParams{
1630				Rule:   android.Cp,
1631				Input:  sharedLibInfo.SharedLibrary,
1632				Output: relocatedLib,
1633			})
1634			j.data = append(j.data, relocatedLib)
1635
1636			directImplementationDeps = append(directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
1637			if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok {
1638				transitiveImplementationDeps = append(transitiveImplementationDeps, info.ImplementationDeps)
1639			}
1640		} else {
1641			ctx.PropertyErrorf("jni_libs", "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep))
1642		}
1643	})
1644
1645	android.SetProvider(ctx, cc.ImplementationDepInfoProvider, &cc.ImplementationDepInfo{
1646		ImplementationDeps: depset.New(depset.PREORDER, directImplementationDeps, transitiveImplementationDeps),
1647	})
1648
1649	j.Library.GenerateAndroidBuildActions(ctx)
1650}
1651
1652func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1653	j.Library.GenerateAndroidBuildActions(ctx)
1654}
1655
1656func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1657	j.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
1658		TestConfigProp:       j.prebuiltTestProperties.Test_config,
1659		TestSuites:           j.prebuiltTestProperties.Test_suites,
1660		DeviceTemplate:       "${JavaTestConfigTemplate}",
1661		HostTemplate:         "${JavaHostTestConfigTemplate}",
1662		HostUnitTestTemplate: "${JavaHostUnitTestConfigTemplate}",
1663	})
1664
1665	j.Import.GenerateAndroidBuildActions(ctx)
1666}
1667
1668type testSdkMemberType struct {
1669	android.SdkMemberTypeBase
1670}
1671
1672func (mt *testSdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) {
1673	ctx.AddVariationDependencies(nil, dependencyTag, names...)
1674}
1675
1676func (mt *testSdkMemberType) IsInstance(module android.Module) bool {
1677	_, ok := module.(*Test)
1678	return ok
1679}
1680
1681func (mt *testSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
1682	return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_test_import")
1683}
1684
1685func (mt *testSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
1686	return &testSdkMemberProperties{}
1687}
1688
1689type testSdkMemberProperties struct {
1690	android.SdkMemberPropertiesBase
1691
1692	JarToExport android.Path
1693	TestConfig  android.Path
1694}
1695
1696func (p *testSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
1697	test := variant.(*Test)
1698
1699	implementationJars := test.ImplementationJars()
1700	if len(implementationJars) != 1 {
1701		panic(fmt.Errorf("there must be only one implementation jar from %q", test.Name()))
1702	}
1703
1704	p.JarToExport = implementationJars[0]
1705	p.TestConfig = test.testConfig
1706}
1707
1708func (p *testSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
1709	builder := ctx.SnapshotBuilder()
1710
1711	exportedJar := p.JarToExport
1712	if exportedJar != nil {
1713		snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(ctx, p.OsPrefix(), ctx.Name())
1714		builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath)
1715
1716		propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
1717	}
1718
1719	testConfig := p.TestConfig
1720	if testConfig != nil {
1721		snapshotRelativeTestConfigPath := sdkSnapshotFilePathForMember(p.OsPrefix(), ctx.Name(), testConfigSuffix)
1722		builder.CopyToSnapshot(testConfig, snapshotRelativeTestConfigPath)
1723		propertySet.AddProperty("test_config", snapshotRelativeTestConfigPath)
1724	}
1725}
1726
1727// java_test builds a and links sources into a `.jar` file for the device, and possibly for the host as well, and
1728// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
1729//
1730// By default, a java_test has a single variant that produces a `.jar` file containing `classes.dex` files that were
1731// compiled against the device bootclasspath.
1732//
1733// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
1734// compiled against the host bootclasspath.
1735func TestFactory() android.Module {
1736	module := &Test{}
1737
1738	module.addHostAndDeviceProperties()
1739	module.AddProperties(&module.testProperties)
1740
1741	module.Module.properties.Installable = proptools.BoolPtr(true)
1742	module.Module.dexpreopter.isTest = true
1743	module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
1744	module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
1745	module.Module.sourceProperties.Top_level_test_target = true
1746
1747	InitJavaModule(module, android.HostAndDeviceSupported)
1748	return module
1749}
1750
1751// java_test_helper_library creates a java library and makes sure that it is added to the appropriate test suite.
1752func TestHelperLibraryFactory() android.Module {
1753	module := &TestHelperLibrary{}
1754
1755	module.addHostAndDeviceProperties()
1756	module.AddProperties(&module.testHelperLibraryProperties)
1757
1758	module.Module.properties.Installable = proptools.BoolPtr(true)
1759	module.Module.dexpreopter.isTest = true
1760	module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
1761	module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
1762
1763	InitJavaModule(module, android.HostAndDeviceSupported)
1764	return module
1765}
1766
1767// java_test_import imports one or more `.jar` files into the build graph as if they were built by a java_test module
1768// and makes sure that it is added to the appropriate test suite.
1769//
1770// By default, a java_test_import has a single variant that expects a `.jar` file containing `.class` files that were
1771// compiled against an Android classpath.
1772//
1773// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
1774// for host modules.
1775func JavaTestImportFactory() android.Module {
1776	module := &JavaTestImport{}
1777
1778	module.AddProperties(
1779		&module.Import.properties,
1780		&module.prebuiltTestProperties)
1781
1782	module.Import.properties.Installable = proptools.BoolPtr(true)
1783
1784	android.InitPrebuiltModule(module, &module.properties.Jars)
1785	android.InitApexModule(module)
1786	InitJavaModule(module, android.HostAndDeviceSupported)
1787	return module
1788}
1789
1790// java_test_host builds a and links sources into a `.jar` file for the host, and creates an `AndroidTest.xml` file to
1791// allow running the test with `atest` or a `TEST_MAPPING` file.
1792//
1793// A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were
1794// compiled against the host bootclasspath.
1795func TestHostFactory() android.Module {
1796	module := &TestHost{}
1797
1798	module.addHostProperties()
1799	module.AddProperties(&module.testProperties)
1800	module.AddProperties(&module.testHostProperties)
1801
1802	InitTestHost(
1803		module,
1804		proptools.BoolPtr(true),
1805		nil,
1806		nil)
1807
1808	InitJavaModuleMultiTargets(module, android.HostSupported)
1809
1810	return module
1811}
1812
1813func InitTestHost(th *TestHost, installable *bool, testSuites []string, autoGenConfig *bool) {
1814	th.properties.Installable = installable
1815	th.testProperties.Auto_gen_config = autoGenConfig
1816	th.testProperties.Test_suites = testSuites
1817	th.sourceProperties.Test_only = proptools.BoolPtr(true)
1818	th.sourceProperties.Top_level_test_target = true
1819}
1820
1821//
1822// Java Binaries (.jar file plus wrapper script)
1823//
1824
1825type binaryProperties struct {
1826	// installable script to execute the resulting jar
1827	Wrapper *string `android:"path,arch_variant"`
1828
1829	// Name of the class containing main to be inserted into the manifest as Main-Class.
1830	Main_class *string
1831
1832	// Names of modules containing JNI libraries that should be installed alongside the binary.
1833	Jni_libs []string `android:"arch_variant"`
1834}
1835
1836type Binary struct {
1837	Library
1838
1839	binaryProperties binaryProperties
1840
1841	wrapperFile android.Path
1842	binaryFile  android.InstallPath
1843
1844	androidMkNamesOfJniLibs []string
1845}
1846
1847func (j *Binary) HostToolPath() android.OptionalPath {
1848	return android.OptionalPathForPath(j.binaryFile)
1849}
1850
1851func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1852	j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName())
1853
1854	// Handle the binary wrapper. This comes before compiling the jar so that the wrapper
1855	// is the first PackagingSpec
1856	if j.binaryProperties.Wrapper != nil {
1857		j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper)
1858	} else {
1859		if ctx.Windows() {
1860			ctx.PropertyErrorf("wrapper", "wrapper is required for Windows")
1861		}
1862
1863		if ctx.Device() {
1864			// device binary should have a main_class property if it does not
1865			// have a specific wrapper, so that a default wrapper can
1866			// be generated for it.
1867			if j.binaryProperties.Main_class == nil {
1868				ctx.PropertyErrorf("main_class", "main_class property "+
1869					"is required for device binary if no default wrapper is assigned")
1870			} else {
1871				wrapper := android.PathForModuleOut(ctx, ctx.ModuleName()+".sh")
1872				jarName := j.Stem() + ".jar"
1873				partition := j.PartitionTag(ctx.DeviceConfig())
1874				ctx.Build(pctx, android.BuildParams{
1875					Rule:   deviceBinaryWrapper,
1876					Output: wrapper,
1877					Args: map[string]string{
1878						"jar_name":   jarName,
1879						"partition":  partition,
1880						"main_class": String(j.binaryProperties.Main_class),
1881					},
1882				})
1883				j.wrapperFile = wrapper
1884			}
1885		} else {
1886			j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh")
1887		}
1888	}
1889
1890	ext := ""
1891	if ctx.Windows() {
1892		ext = ".bat"
1893	}
1894
1895	// The host installation rules make the installed wrapper depend on all the dependencies
1896	// of the wrapper variant, which will include the common variant's jar file and any JNI
1897	// libraries.  This is verified by TestBinary. Also make it depend on the jar file so that
1898	// the binary file timestamp will update when the jar file timestamp does. The jar file is
1899	// built later on, in j.Library.GenerateAndroidBuildActions, so we have to create an identical
1900	// installpath representing it here.
1901	j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"),
1902		ctx.ModuleName()+ext, j.wrapperFile, j.getJarInstallDir(ctx).Join(ctx, j.Stem()+".jar"))
1903
1904	// Set the jniLibs of this binary.
1905	// These will be added to `LOCAL_REQUIRED_MODULES`, and the kati packaging system will
1906	// install these alongside the java binary.
1907	ctx.VisitDirectDepsWithTag(jniInstallTag, func(jni android.Module) {
1908		// Use the BaseModuleName of the dependency (without any prebuilt_ prefix)
1909		bmn, _ := jni.(interface{ BaseModuleName() string })
1910		j.androidMkNamesOfJniLibs = append(j.androidMkNamesOfJniLibs, bmn.BaseModuleName()+":"+jni.Target().Arch.ArchType.Bitness())
1911	})
1912	// Check that native libraries are not listed in `required`. Prompt users to use `jni_libs` instead.
1913	ctx.VisitDirectDepsWithTag(android.RequiredDepTag, func(dep android.Module) {
1914		if _, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider); hasSharedLibraryInfo {
1915			ctx.ModuleErrorf("cc_library %s is no longer supported in `required` of java_binary modules. Please use jni_libs instead.", dep.Name())
1916		}
1917	})
1918
1919	// Compile the jar
1920	if j.binaryProperties.Main_class != nil {
1921		if j.properties.Manifest != nil {
1922			ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set")
1923		}
1924		manifestFile := android.PathForModuleOut(ctx, "manifest.txt")
1925		GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class))
1926		j.overrideManifest = android.OptionalPathForPath(manifestFile)
1927	}
1928
1929	j.Library.GenerateAndroidBuildActions(ctx)
1930}
1931
1932func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
1933	j.deps(ctx)
1934	// These dependencies ensure the installation rules will install the jar file when the
1935	// wrapper is installed, and the jni libraries when the wrapper is installed.
1936	if ctx.Os().Class == android.Host {
1937		ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniInstallTag, j.binaryProperties.Jni_libs...)
1938	} else if ctx.Os().Class == android.Device {
1939		ctx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), jniInstallTag, j.binaryProperties.Jni_libs...)
1940	} else {
1941		ctx.ModuleErrorf("Unknown os class")
1942	}
1943}
1944
1945// java_binary builds a `.jar` file and a shell script that executes it for the device, and possibly for the host
1946// as well.
1947//
1948// By default, a java_binary has a single variant that produces a `.jar` file containing `classes.dex` files that were
1949// compiled against the device bootclasspath.
1950//
1951// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
1952// compiled against the host bootclasspath.
1953func BinaryFactory() android.Module {
1954	module := &Binary{}
1955
1956	module.addHostAndDeviceProperties()
1957	module.AddProperties(&module.binaryProperties, &module.sourceProperties)
1958
1959	module.Module.properties.Installable = proptools.BoolPtr(true)
1960
1961	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
1962	android.InitDefaultableModule(module)
1963
1964	return module
1965}
1966
1967// java_binary_host builds a `.jar` file and a shell script that executes it for the host.
1968//
1969// A java_binary_host has a single variant that produces a `.jar` file containing `.class` files that were
1970// compiled against the host bootclasspath.
1971func BinaryHostFactory() android.Module {
1972	module := &Binary{}
1973
1974	module.addHostProperties()
1975	module.AddProperties(&module.binaryProperties)
1976
1977	module.Module.properties.Installable = proptools.BoolPtr(true)
1978
1979	android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
1980	android.InitDefaultableModule(module)
1981	return module
1982}
1983
1984type JavaApiContribution struct {
1985	android.ModuleBase
1986	android.DefaultableModuleBase
1987	embeddableInModuleAndImport
1988
1989	properties struct {
1990		// name of the API surface
1991		Api_surface *string
1992
1993		// relative path to the API signature text file
1994		Api_file *string `android:"path"`
1995	}
1996}
1997
1998func ApiContributionFactory() android.Module {
1999	module := &JavaApiContribution{}
2000	android.InitAndroidModule(module)
2001	android.InitDefaultableModule(module)
2002	module.AddProperties(&module.properties)
2003	module.initModuleAndImport(module)
2004	return module
2005}
2006
2007type JavaApiImportInfo struct {
2008	ApiFile    android.Path
2009	ApiSurface string
2010}
2011
2012var JavaApiImportProvider = blueprint.NewProvider[JavaApiImportInfo]()
2013
2014func (ap *JavaApiContribution) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2015	var apiFile android.Path = nil
2016	if apiFileString := ap.properties.Api_file; apiFileString != nil {
2017		apiFile = android.PathForModuleSrc(ctx, String(apiFileString))
2018	}
2019
2020	android.SetProvider(ctx, JavaApiImportProvider, JavaApiImportInfo{
2021		ApiFile:    apiFile,
2022		ApiSurface: proptools.String(ap.properties.Api_surface),
2023	})
2024}
2025
2026type ApiLibrary struct {
2027	android.ModuleBase
2028	android.DefaultableModuleBase
2029
2030	hiddenAPI
2031	dexer
2032	embeddableInModuleAndImport
2033
2034	properties JavaApiLibraryProperties
2035
2036	stubsSrcJar               android.WritablePath
2037	stubsJar                  android.WritablePath
2038	stubsJarWithoutStaticLibs android.WritablePath
2039	extractedSrcJar           android.WritablePath
2040	// .dex of stubs, used for hiddenapi processing
2041	dexJarFile OptionalDexJarPath
2042
2043	validationPaths android.Paths
2044
2045	stubsType StubsType
2046
2047	aconfigProtoFiles android.Paths
2048}
2049
2050type JavaApiLibraryProperties struct {
2051	// name of the API surface
2052	Api_surface *string
2053
2054	// list of Java API contribution modules that consists this API surface
2055	// This is a list of Soong modules
2056	Api_contributions []string
2057
2058	// List of flags to be passed to the javac compiler to generate jar file
2059	Javacflags []string
2060
2061	// List of shared java libs that this module has dependencies to and
2062	// should be passed as classpath in javac invocation
2063	Libs proptools.Configurable[[]string]
2064
2065	// List of java libs that this module has static dependencies to and will be
2066	// merge zipped after metalava invocation
2067	Static_libs proptools.Configurable[[]string]
2068
2069	// Version of previously released API file for compatibility check.
2070	Previous_api *string `android:"path"`
2071
2072	// java_system_modules module providing the jar to be added to the
2073	// bootclasspath when compiling the stubs.
2074	// The jar will also be passed to metalava as a classpath to
2075	// generate compilable stubs.
2076	System_modules *string
2077
2078	// If true, the module runs validation on the API signature files provided
2079	// by the modules passed via api_contributions by checking if the files are
2080	// in sync with the source Java files. However, the environment variable
2081	// DISABLE_STUB_VALIDATION has precedence over this property.
2082	Enable_validation *bool
2083
2084	// Type of stubs the module should generate. Must be one of "everything", "runtime" or
2085	// "exportable". Defaults to "everything".
2086	// - "everything" stubs include all non-flagged apis and flagged apis, regardless of the state
2087	// of the flag.
2088	// - "runtime" stubs include all non-flagged apis and flagged apis that are ENABLED or
2089	// READ_WRITE, and all other flagged apis are stripped.
2090	// - "exportable" stubs include all non-flagged apis and flagged apis that are ENABLED and
2091	// READ_ONLY, and all other flagged apis are stripped.
2092	Stubs_type *string
2093
2094	// List of aconfig_declarations module names that the stubs generated in this module
2095	// depend on.
2096	Aconfig_declarations []string
2097
2098	// List of hard coded filegroups containing Metalava config files that are passed to every
2099	// Metalava invocation that this module performs. See addMetalavaConfigFilesToCmd.
2100	ConfigFiles []string `android:"path" blueprint:"mutated"`
2101
2102	// If not blank, set to the version of the sdk to compile against.
2103	// Defaults to an empty string, which compiles the module against the private platform APIs.
2104	// Values are of one of the following forms:
2105	// 1) numerical API level, "current", "none", or "core_platform"
2106	// 2) An SDK kind with an API level: "<sdk kind>_<API level>"
2107	// See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds.
2108	// If the SDK kind is empty, it will be set to public.
2109	Sdk_version *string
2110}
2111
2112func ApiLibraryFactory() android.Module {
2113	module := &ApiLibrary{}
2114	module.AddProperties(&module.properties)
2115	module.properties.ConfigFiles = getMetalavaConfigFilegroupReference()
2116	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
2117	module.initModuleAndImport(module)
2118	android.InitDefaultableModule(module)
2119	return module
2120}
2121
2122func (al *ApiLibrary) ApiSurface() *string {
2123	return al.properties.Api_surface
2124}
2125
2126func (al *ApiLibrary) StubsJar() android.Path {
2127	return al.stubsJar
2128}
2129
2130func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
2131	srcs android.Paths, homeDir android.WritablePath,
2132	classpath android.Paths, configFiles android.Paths) *android.RuleBuilderCommand {
2133	rule.Command().Text("rm -rf").Flag(homeDir.String())
2134	rule.Command().Text("mkdir -p").Flag(homeDir.String())
2135
2136	cmd := rule.Command()
2137	cmd.FlagWithArg("ANDROID_PREFS_ROOT=", homeDir.String())
2138
2139	if metalavaUseRbe(ctx) {
2140		rule.Remoteable(android.RemoteRuleSupports{RBE: true})
2141		execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
2142		labels := map[string]string{"type": "tool", "name": "metalava"}
2143
2144		pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16")
2145		rule.Rewrapper(&remoteexec.REParams{
2146			Labels:          labels,
2147			ExecStrategy:    execStrategy,
2148			ToolchainInputs: []string{config.JavaCmd(ctx).String()},
2149			Platform:        map[string]string{remoteexec.PoolKey: pool},
2150		})
2151	}
2152
2153	cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
2154		Flag(config.JavacVmFlags).
2155		Flag("-J--add-opens=java.base/java.util=ALL-UNNAMED").
2156		FlagWithInputList("--source-files ", srcs, " ")
2157
2158	cmd.Flag("--color").
2159		Flag("--quiet").
2160		Flag("--include-annotations").
2161		// The flag makes nullability issues as warnings rather than errors by replacing
2162		// @Nullable/@NonNull in the listed packages APIs with @RecentlyNullable/@RecentlyNonNull,
2163		// and these packages are meant to have everything annotated
2164		// @RecentlyNullable/@RecentlyNonNull.
2165		FlagWithArg("--force-convert-to-warning-nullability-annotations ", "+*:-android.*:+android.icu.*:-dalvik.*").
2166		FlagWithArg("--repeat-errors-max ", "10").
2167		FlagWithArg("--hide ", "UnresolvedImport").
2168		FlagWithArg("--hide ", "InvalidNullabilityOverride").
2169		FlagWithArg("--hide ", "ChangedDefault")
2170
2171	addMetalavaConfigFilesToCmd(cmd, configFiles)
2172
2173	if len(classpath) == 0 {
2174		// The main purpose of the `--api-class-resolution api` option is to force metalava to ignore
2175		// classes on the classpath when an API file contains missing classes. However, as this command
2176		// does not specify `--classpath` this is not needed for that. However, this is also used as a
2177		// signal to the special metalava code for generating stubs from text files that it needs to add
2178		// some additional items into the API (e.g. default constructors).
2179		cmd.FlagWithArg("--api-class-resolution ", "api")
2180	} else {
2181		cmd.FlagWithArg("--api-class-resolution ", "api:classpath")
2182		cmd.FlagWithInputList("--classpath ", classpath, ":")
2183	}
2184
2185	return cmd
2186}
2187
2188func (al *ApiLibrary) HeaderJars() android.Paths {
2189	return android.Paths{al.stubsJar}
2190}
2191
2192func (al *ApiLibrary) OutputDirAndDeps() (android.Path, android.Paths) {
2193	return nil, nil
2194}
2195
2196func (al *ApiLibrary) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath) {
2197	if stubsDir.Valid() {
2198		cmd.FlagWithArg("--stubs ", stubsDir.String())
2199	}
2200}
2201
2202func (al *ApiLibrary) addValidation(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, validationPaths android.Paths) {
2203	for _, validationPath := range validationPaths {
2204		cmd.Validation(validationPath)
2205	}
2206}
2207
2208func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
2209	apiContributions := al.properties.Api_contributions
2210	addValidations := !ctx.Config().IsEnvTrue("DISABLE_STUB_VALIDATION") &&
2211		!ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") &&
2212		proptools.BoolDefault(al.properties.Enable_validation, true)
2213	for _, apiContributionName := range apiContributions {
2214		ctx.AddDependency(ctx.Module(), javaApiContributionTag, apiContributionName)
2215
2216		// Add the java_api_contribution module generating droidstubs module
2217		// as dependency when validation adding conditions are met and
2218		// the java_api_contribution module name has ".api.contribution" suffix.
2219		// All droidstubs-generated modules possess the suffix in the name,
2220		// but there is no such guarantee for tests.
2221		if addValidations {
2222			if strings.HasSuffix(apiContributionName, ".api.contribution") {
2223				ctx.AddDependency(ctx.Module(), metalavaCurrentApiTimestampTag, strings.TrimSuffix(apiContributionName, ".api.contribution"))
2224			} else {
2225				ctx.ModuleErrorf("Validation is enabled for module %s but a "+
2226					"current timestamp provider is not found for the api "+
2227					"contribution %s",
2228					ctx.ModuleName(),
2229					apiContributionName,
2230				)
2231			}
2232		}
2233	}
2234	if ctx.Device() {
2235		sdkDep := decodeSdkDep(ctx, android.SdkContext(al))
2236		if sdkDep.useModule {
2237			ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
2238			ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...)
2239			ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
2240
2241		}
2242	}
2243	ctx.AddVariationDependencies(nil, libTag, al.properties.Libs.GetOrDefault(ctx, nil)...)
2244	ctx.AddVariationDependencies(nil, staticLibTag, al.properties.Static_libs.GetOrDefault(ctx, nil)...)
2245
2246	for _, aconfigDeclarationsName := range al.properties.Aconfig_declarations {
2247		ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationsName)
2248	}
2249}
2250
2251// Map where key is the api scope name and value is the int value
2252// representing the order of the api scope, narrowest to the widest
2253var scopeOrderMap = AllApiScopes.MapToIndex(
2254	func(s *apiScope) string { return s.name })
2255
2256func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo) []JavaApiImportInfo {
2257	for _, srcFileInfo := range srcFilesInfo {
2258		if srcFileInfo.ApiSurface == "" {
2259			ctx.ModuleErrorf("Api surface not defined for the associated api file %s", srcFileInfo.ApiFile)
2260		}
2261	}
2262	sort.Slice(srcFilesInfo, func(i, j int) bool {
2263		return scopeOrderMap[srcFilesInfo[i].ApiSurface] < scopeOrderMap[srcFilesInfo[j].ApiSurface]
2264	})
2265
2266	return srcFilesInfo
2267}
2268
2269var validstubsType = []StubsType{Everything, Runtime, Exportable}
2270
2271func (al *ApiLibrary) validateProperties(ctx android.ModuleContext) {
2272	if al.properties.Stubs_type == nil {
2273		ctx.ModuleErrorf("java_api_library module type must specify stubs_type property.")
2274	} else {
2275		al.stubsType = StringToStubsType(proptools.String(al.properties.Stubs_type))
2276	}
2277
2278	if !android.InList(al.stubsType, validstubsType) {
2279		ctx.PropertyErrorf("stubs_type", "%s is not a valid stubs_type property value. "+
2280			"Must be one of %s.", proptools.String(al.properties.Stubs_type), validstubsType)
2281	}
2282}
2283
2284func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2285	al.validateProperties(ctx)
2286
2287	rule := android.NewRuleBuilder(pctx, ctx)
2288
2289	rule.Sbox(android.PathForModuleOut(ctx, "metalava"),
2290		android.PathForModuleOut(ctx, "metalava.sbox.textproto")).
2291		SandboxInputs()
2292
2293	stubsDir := android.OptionalPathForPath(android.PathForModuleOut(ctx, "metalava", "stubsDir"))
2294	rule.Command().Text("rm -rf").Text(stubsDir.String())
2295	rule.Command().Text("mkdir -p").Text(stubsDir.String())
2296
2297	homeDir := android.PathForModuleOut(ctx, "metalava", "home")
2298
2299	var srcFilesInfo []JavaApiImportInfo
2300	var classPaths android.Paths
2301	var bootclassPaths android.Paths
2302	var staticLibs android.Paths
2303	var systemModulesPaths android.Paths
2304	ctx.VisitDirectDeps(func(dep android.Module) {
2305		tag := ctx.OtherModuleDependencyTag(dep)
2306		switch tag {
2307		case javaApiContributionTag:
2308			provider, _ := android.OtherModuleProvider(ctx, dep, JavaApiImportProvider)
2309			if provider.ApiFile == nil && !ctx.Config().AllowMissingDependencies() {
2310				ctx.ModuleErrorf("Error: %s has an empty api file.", dep.Name())
2311			}
2312			srcFilesInfo = append(srcFilesInfo, provider)
2313		case libTag:
2314			if provider, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
2315				classPaths = append(classPaths, provider.HeaderJars...)
2316				al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.AconfigIntermediateCacheOutputPaths...)
2317			}
2318		case bootClasspathTag:
2319			if provider, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
2320				bootclassPaths = append(bootclassPaths, provider.HeaderJars...)
2321				al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.AconfigIntermediateCacheOutputPaths...)
2322			}
2323		case staticLibTag:
2324			if provider, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
2325				staticLibs = append(staticLibs, provider.HeaderJars...)
2326				al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.AconfigIntermediateCacheOutputPaths...)
2327			}
2328		case systemModulesTag:
2329			if sm, ok := android.OtherModuleProvider(ctx, dep, SystemModulesProvider); ok {
2330				systemModulesPaths = append(systemModulesPaths, sm.HeaderJars...)
2331			}
2332		case metalavaCurrentApiTimestampTag:
2333			if currentApiTimestampProvider, ok := dep.(currentApiTimestampProvider); ok {
2334				al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp())
2335			}
2336		case aconfigDeclarationTag:
2337			if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
2338				al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPath)
2339			} else if provider, ok := android.OtherModuleProvider(ctx, dep, android.CodegenInfoProvider); ok {
2340				al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPaths...)
2341			} else {
2342				ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+
2343					"module type is allowed for flags_packages property, but %s is neither "+
2344					"of these supported module types",
2345					dep.Name(),
2346				)
2347			}
2348		}
2349	})
2350
2351	srcFilesInfo = al.sortApiFilesByApiScope(ctx, srcFilesInfo)
2352	var srcFiles android.Paths
2353	for _, srcFileInfo := range srcFilesInfo {
2354		srcFiles = append(srcFiles, android.PathForSource(ctx, srcFileInfo.ApiFile.String()))
2355	}
2356
2357	if srcFiles == nil && !ctx.Config().AllowMissingDependencies() {
2358		ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName())
2359	}
2360
2361	configFiles := android.PathsForModuleSrc(ctx, al.properties.ConfigFiles)
2362
2363	combinedPaths := append(([]android.Path)(nil), systemModulesPaths...)
2364	combinedPaths = append(combinedPaths, classPaths...)
2365	combinedPaths = append(combinedPaths, bootclassPaths...)
2366	cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, combinedPaths, configFiles)
2367
2368	al.stubsFlags(ctx, cmd, stubsDir)
2369
2370	previousApi := String(al.properties.Previous_api)
2371	if previousApi != "" {
2372		previousApiFiles := android.PathsForModuleSrc(ctx, []string{previousApi})
2373		cmd.FlagForEachInput("--migrate-nullness ", previousApiFiles)
2374	}
2375
2376	al.addValidation(ctx, cmd, al.validationPaths)
2377
2378	generateRevertAnnotationArgs(ctx, cmd, al.stubsType, al.aconfigProtoFiles)
2379
2380	al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar")
2381	al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, "metalava", "stubs.jar")
2382	al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName()))
2383
2384	rule.Command().
2385		BuiltTool("soong_zip").
2386		Flag("-write_if_changed").
2387		Flag("-jar").
2388		FlagWithOutput("-o ", al.stubsSrcJar).
2389		FlagWithArg("-C ", stubsDir.String()).
2390		FlagWithArg("-D ", stubsDir.String())
2391
2392	rule.Build("metalava", "metalava merged text")
2393
2394	javacFlags := javaBuilderFlags{
2395		javaVersion:   getStubsJavaVersion(),
2396		javacFlags:    strings.Join(al.properties.Javacflags, " "),
2397		classpath:     classpath(classPaths),
2398		bootClasspath: classpath(append(systemModulesPaths, bootclassPaths...)),
2399	}
2400
2401	annoSrcJar := android.PathForModuleOut(ctx, ctx.ModuleName(), "anno.srcjar")
2402
2403	TransformJavaToClasses(ctx, al.stubsJarWithoutStaticLibs, 0, android.Paths{},
2404		android.Paths{al.stubsSrcJar}, annoSrcJar, javacFlags, android.Paths{})
2405
2406	builder := android.NewRuleBuilder(pctx, ctx)
2407	builder.Command().
2408		BuiltTool("merge_zips").
2409		Output(al.stubsJar).
2410		Inputs(android.Paths{al.stubsJarWithoutStaticLibs}).
2411		Inputs(staticLibs)
2412	builder.Build("merge_zips", "merge jar files")
2413
2414	// compile stubs to .dex for hiddenapi processing
2415	dexParams := &compileDexParams{
2416		flags:         javacFlags,
2417		sdkVersion:    al.SdkVersion(ctx),
2418		minSdkVersion: al.MinSdkVersion(ctx),
2419		classesJar:    al.stubsJar,
2420		jarName:       ctx.ModuleName() + ".jar",
2421	}
2422	dexOutputFile, _ := al.dexer.compileDex(ctx, dexParams)
2423	uncompressed := true
2424	al.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), al.stubsJar, &uncompressed)
2425	dexOutputFile = al.hiddenAPIEncodeDex(ctx, dexOutputFile)
2426	al.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
2427
2428	ctx.Phony(ctx.ModuleName(), al.stubsJar)
2429
2430	android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
2431		HeaderJars:                             android.PathsIfNonNil(al.stubsJar),
2432		LocalHeaderJars:                        android.PathsIfNonNil(al.stubsJar),
2433		TransitiveStaticLibsHeaderJars:         depset.New(depset.PREORDER, android.PathsIfNonNil(al.stubsJar), nil),
2434		TransitiveStaticLibsImplementationJars: depset.New(depset.PREORDER, android.PathsIfNonNil(al.stubsJar), nil),
2435		ImplementationAndResourcesJars:         android.PathsIfNonNil(al.stubsJar),
2436		ImplementationJars:                     android.PathsIfNonNil(al.stubsJar),
2437		AidlIncludeDirs:                        android.Paths{},
2438		StubsLinkType:                          Stubs,
2439		// No aconfig libraries on api libraries
2440	})
2441}
2442
2443func (al *ApiLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
2444	return al.dexJarFile
2445}
2446
2447func (al *ApiLibrary) DexJarInstallPath() android.Path {
2448	return al.dexJarFile.Path()
2449}
2450
2451func (al *ApiLibrary) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
2452	return nil
2453}
2454
2455// Most java_api_library constitues the sdk, but there are some java_api_library that
2456// does not contribute to the api surface. Such modules are allowed to set sdk_version
2457// other than "none"
2458func (al *ApiLibrary) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
2459	return android.SdkSpecFrom(ctx, proptools.String(al.properties.Sdk_version))
2460}
2461
2462// java_api_library is always at "current". Return FutureApiLevel
2463func (al *ApiLibrary) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
2464	return al.SdkVersion(ctx).ApiLevel
2465}
2466
2467func (al *ApiLibrary) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
2468	return al.SdkVersion(ctx).ApiLevel
2469}
2470
2471func (al *ApiLibrary) SystemModules() string {
2472	return proptools.String(al.properties.System_modules)
2473}
2474
2475func (al *ApiLibrary) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
2476	return al.SdkVersion(ctx).ApiLevel
2477}
2478
2479func (al *ApiLibrary) IDEInfo(ctx android.BaseModuleContext, i *android.IdeInfo) {
2480	i.Deps = append(i.Deps, al.ideDeps(ctx)...)
2481	i.Libs = append(i.Libs, al.properties.Libs.GetOrDefault(ctx, nil)...)
2482	i.Static_libs = append(i.Static_libs, al.properties.Static_libs.GetOrDefault(ctx, nil)...)
2483	i.SrcJars = append(i.SrcJars, al.stubsSrcJar.String())
2484}
2485
2486// deps of java_api_library for module_bp_java_deps.json
2487func (al *ApiLibrary) ideDeps(ctx android.BaseModuleContext) []string {
2488	ret := []string{}
2489	ret = append(ret, al.properties.Libs.GetOrDefault(ctx, nil)...)
2490	ret = append(ret, al.properties.Static_libs.GetOrDefault(ctx, nil)...)
2491	if proptools.StringDefault(al.properties.System_modules, "none") != "none" {
2492		ret = append(ret, proptools.String(al.properties.System_modules))
2493	}
2494	// Other non java_library dependencies like java_api_contribution are ignored for now.
2495	return ret
2496}
2497
2498// implement the following interfaces for hiddenapi processing
2499var _ hiddenAPIModule = (*ApiLibrary)(nil)
2500var _ UsesLibraryDependency = (*ApiLibrary)(nil)
2501var _ android.SdkContext = (*ApiLibrary)(nil)
2502
2503// implement the following interface for IDE completion.
2504var _ android.IDEInfo = (*ApiLibrary)(nil)
2505
2506//
2507// Java prebuilts
2508//
2509
2510type ImportProperties struct {
2511	Jars []string `android:"path,arch_variant"`
2512
2513	// The version of the SDK that the source prebuilt file was built against. Defaults to the
2514	// current version if not specified.
2515	Sdk_version *string
2516
2517	// The minimum version of the SDK that this module supports. Defaults to sdk_version if not
2518	// specified.
2519	Min_sdk_version *string
2520
2521	// The max sdk version placeholder used to replace maxSdkVersion attributes on permission
2522	// and uses-permission tags in manifest_fixer.
2523	Replace_max_sdk_version_placeholder *string
2524
2525	Installable *bool
2526
2527	// If not empty, classes are restricted to the specified packages and their sub-packages.
2528	Permitted_packages []string
2529
2530	// List of shared java libs that this module has dependencies to
2531	Libs []string
2532
2533	// List of static java libs that this module has dependencies to
2534	Static_libs proptools.Configurable[[]string]
2535
2536	// List of files to remove from the jar file(s)
2537	Exclude_files []string
2538
2539	// List of directories to remove from the jar file(s)
2540	Exclude_dirs []string
2541
2542	// if set to true, run Jetifier against .jar file. Defaults to false.
2543	Jetifier *bool
2544
2545	// set the name of the output
2546	Stem *string
2547
2548	Aidl struct {
2549		// directories that should be added as include directories for any aidl sources of modules
2550		// that depend on this module, as well as to aidl for this module.
2551		Export_include_dirs []string
2552	}
2553
2554	// Name of the source soong module that gets shadowed by this prebuilt
2555	// If unspecified, follows the naming convention that the source module of
2556	// the prebuilt is Name() without "prebuilt_" prefix
2557	Source_module_name *string
2558
2559	// Non-nil if this java_import module was dynamically created by a java_sdk_library_import
2560	// The name is the undecorated name of the java_sdk_library as it appears in the blueprint file
2561	// (without any prebuilt_ prefix)
2562	Created_by_java_sdk_library_name *string `blueprint:"mutated"`
2563
2564	// Property signifying whether the module provides stubs jar or not.
2565	Is_stubs_module *bool
2566}
2567
2568type Import struct {
2569	android.ModuleBase
2570	android.DefaultableModuleBase
2571	android.ApexModuleBase
2572	prebuilt android.Prebuilt
2573
2574	// Functionality common to Module and Import.
2575	embeddableInModuleAndImport
2576
2577	hiddenAPI
2578	dexer
2579	dexpreopter
2580
2581	properties ImportProperties
2582
2583	// output file containing classes.dex and resources
2584	dexJarFile        OptionalDexJarPath
2585	dexJarFileErr     error
2586	dexJarInstallFile android.Path
2587
2588	combinedImplementationFile android.Path
2589	combinedHeaderFile         android.Path
2590	classLoaderContexts        dexpreopt.ClassLoaderContextMap
2591	exportAidlIncludeDirs      android.Paths
2592
2593	hideApexVariantFromMake bool
2594
2595	sdkVersion    android.SdkSpec
2596	minSdkVersion android.ApiLevel
2597
2598	stubsLinkType StubsLinkType
2599}
2600
2601var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil)
2602
2603func (j *Import) PermittedPackagesForUpdatableBootJars() []string {
2604	return j.properties.Permitted_packages
2605}
2606
2607func (j *Import) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
2608	return android.SdkSpecFrom(ctx, String(j.properties.Sdk_version))
2609}
2610
2611func (j *Import) SystemModules() string {
2612	return "none"
2613}
2614
2615func (j *Import) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
2616	if j.properties.Min_sdk_version != nil {
2617		return android.ApiLevelFrom(ctx, *j.properties.Min_sdk_version)
2618	}
2619	return j.SdkVersion(ctx).ApiLevel
2620}
2621
2622func (j *Import) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
2623	if j.properties.Replace_max_sdk_version_placeholder != nil {
2624		return android.ApiLevelFrom(ctx, *j.properties.Replace_max_sdk_version_placeholder)
2625	}
2626	// Default is PrivateApiLevel
2627	return android.SdkSpecPrivate.ApiLevel
2628}
2629
2630func (j *Import) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
2631	return j.SdkVersion(ctx).ApiLevel
2632}
2633
2634func (j *Import) Prebuilt() *android.Prebuilt {
2635	return &j.prebuilt
2636}
2637
2638func (j *Import) PrebuiltSrcs() []string {
2639	return j.properties.Jars
2640}
2641
2642func (j *Import) BaseModuleName() string {
2643	return proptools.StringDefault(j.properties.Source_module_name, j.ModuleBase.Name())
2644}
2645
2646func (j *Import) Name() string {
2647	return j.prebuilt.Name(j.ModuleBase.Name())
2648}
2649
2650func (j *Import) Stem() string {
2651	return proptools.StringDefault(j.properties.Stem, j.BaseModuleName())
2652}
2653
2654func (j *Import) CreatedByJavaSdkLibraryName() *string {
2655	return j.properties.Created_by_java_sdk_library_name
2656}
2657
2658func (a *Import) JacocoReportClassesFile() android.Path {
2659	return nil
2660}
2661
2662func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
2663	ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
2664	ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs.GetOrDefault(ctx, nil)...)
2665
2666	if ctx.Device() && Bool(j.dexProperties.Compile_dex) {
2667		sdkDeps(ctx, android.SdkContext(j), j.dexer)
2668	}
2669}
2670
2671func (j *Import) commonBuildActions(ctx android.ModuleContext) {
2672	j.sdkVersion = j.SdkVersion(ctx)
2673	j.minSdkVersion = j.MinSdkVersion(ctx)
2674
2675	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
2676	if !apexInfo.IsForPlatform() {
2677		j.hideApexVariantFromMake = true
2678	}
2679
2680	if ctx.Windows() {
2681		j.HideFromMake()
2682	}
2683
2684	if proptools.Bool(j.properties.Is_stubs_module) {
2685		j.stubsLinkType = Stubs
2686	} else {
2687		j.stubsLinkType = Implementation
2688	}
2689}
2690
2691func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2692	j.commonBuildActions(ctx)
2693
2694	j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
2695
2696	var flags javaBuilderFlags
2697
2698	var transitiveClasspathHeaderJars []depset.DepSet[android.Path]
2699	var transitiveBootClasspathHeaderJars []depset.DepSet[android.Path]
2700	var transitiveStaticLibsHeaderJars []depset.DepSet[android.Path]
2701	var transitiveStaticLibsImplementationJars []depset.DepSet[android.Path]
2702	var transitiveStaticLibsResourceJars []depset.DepSet[android.Path]
2703
2704	j.collectTransitiveHeaderJarsForR8(ctx)
2705	var staticJars android.Paths
2706	var staticResourceJars android.Paths
2707	var staticHeaderJars android.Paths
2708	ctx.VisitDirectDeps(func(module android.Module) {
2709		tag := ctx.OtherModuleDependencyTag(module)
2710		if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
2711			switch tag {
2712			case libTag, sdkLibTag:
2713				flags.classpath = append(flags.classpath, dep.HeaderJars...)
2714				flags.dexClasspath = append(flags.dexClasspath, dep.HeaderJars...)
2715				transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
2716			case staticLibTag:
2717				flags.classpath = append(flags.classpath, dep.HeaderJars...)
2718				staticJars = append(staticJars, dep.ImplementationJars...)
2719				staticResourceJars = append(staticResourceJars, dep.ResourceJars...)
2720				staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...)
2721				transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
2722				transitiveStaticLibsHeaderJars = append(transitiveStaticLibsHeaderJars, dep.TransitiveStaticLibsHeaderJars)
2723				transitiveStaticLibsImplementationJars = append(transitiveStaticLibsImplementationJars, dep.TransitiveStaticLibsImplementationJars)
2724				transitiveStaticLibsResourceJars = append(transitiveStaticLibsResourceJars, dep.TransitiveStaticLibsResourceJars)
2725			case bootClasspathTag:
2726				flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...)
2727				transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
2728			}
2729		} else if _, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
2730			switch tag {
2731			case libTag, sdkLibTag:
2732				sdkInfo, _ := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider)
2733				generatingLibsString := android.PrettyConcat(
2734					getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or")
2735				ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString)
2736			}
2737		}
2738
2739		addCLCFromDep(ctx, module, j.classLoaderContexts)
2740	})
2741
2742	localJars := android.PathsForModuleSrc(ctx, j.properties.Jars)
2743	jarName := j.Stem() + ".jar"
2744
2745	// Combine only the local jars together for use in transitive classpaths.
2746	// Always pass input jar through TransformJarsToJar to strip module-info.class from prebuilts.
2747	localCombinedHeaderJar := android.PathForModuleOut(ctx, "local-combined", jarName)
2748	TransformJarsToJar(ctx, localCombinedHeaderJar, "combine local prebuilt implementation jars", localJars, android.OptionalPath{},
2749		false, j.properties.Exclude_files, j.properties.Exclude_dirs)
2750	localStrippedJars := android.Paths{localCombinedHeaderJar}
2751
2752	completeStaticLibsHeaderJars := depset.New(depset.PREORDER, localStrippedJars, transitiveStaticLibsHeaderJars)
2753	completeStaticLibsImplementationJars := depset.New(depset.PREORDER, localStrippedJars, transitiveStaticLibsImplementationJars)
2754	completeStaticLibsResourceJars := depset.New(depset.PREORDER, nil, transitiveStaticLibsResourceJars)
2755
2756	// Always pass the input jars to TransformJarsToJar, even if there is only a single jar, we need the output
2757	// file of the module to be named jarName.
2758	var outputFile android.Path
2759	combinedImplementationJar := android.PathForModuleOut(ctx, "combined", jarName)
2760	var implementationJars android.Paths
2761	if ctx.Config().UseTransitiveJarsInClasspath() {
2762		implementationJars = completeStaticLibsImplementationJars.ToList()
2763	} else {
2764		implementationJars = append(slices.Clone(localJars), staticJars...)
2765	}
2766	TransformJarsToJar(ctx, combinedImplementationJar, "combine prebuilt implementation jars", implementationJars, android.OptionalPath{},
2767		false, j.properties.Exclude_files, j.properties.Exclude_dirs)
2768	outputFile = combinedImplementationJar
2769
2770	// If no dependencies have separate header jars then there is no need to create a separate
2771	// header jar for this module.
2772	reuseImplementationJarAsHeaderJar := slices.Equal(staticJars, staticHeaderJars)
2773
2774	var resourceJarFile android.Path
2775	if len(staticResourceJars) > 1 {
2776		combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
2777		TransformJarsToJar(ctx, combinedJar, "for resources", staticResourceJars, android.OptionalPath{},
2778			false, nil, nil)
2779		resourceJarFile = combinedJar
2780	} else if len(staticResourceJars) == 1 {
2781		resourceJarFile = staticResourceJars[0]
2782	}
2783
2784	var headerJar android.Path
2785	if reuseImplementationJarAsHeaderJar {
2786		headerJar = outputFile
2787	} else {
2788		var headerJars android.Paths
2789		if ctx.Config().UseTransitiveJarsInClasspath() {
2790			headerJars = completeStaticLibsHeaderJars.ToList()
2791		} else {
2792			headerJars = append(slices.Clone(localJars), staticHeaderJars...)
2793		}
2794		headerOutputFile := android.PathForModuleOut(ctx, "turbine-combined", jarName)
2795		TransformJarsToJar(ctx, headerOutputFile, "combine prebuilt header jars", headerJars, android.OptionalPath{},
2796			false, j.properties.Exclude_files, j.properties.Exclude_dirs)
2797		headerJar = headerOutputFile
2798	}
2799
2800	if Bool(j.properties.Jetifier) {
2801		jetifierOutputFile := android.PathForModuleOut(ctx, "jetifier", jarName)
2802		TransformJetifier(ctx, jetifierOutputFile, outputFile)
2803		outputFile = jetifierOutputFile
2804
2805		if !reuseImplementationJarAsHeaderJar {
2806			jetifierHeaderJar := android.PathForModuleOut(ctx, "jetifier-headers", jarName)
2807			TransformJetifier(ctx, jetifierHeaderJar, headerJar)
2808			headerJar = jetifierHeaderJar
2809		} else {
2810			headerJar = outputFile
2811		}
2812
2813		// Enabling jetifier requires modifying classes from transitive dependencies, disable transitive
2814		// classpath and use the combined header jar instead.
2815		completeStaticLibsHeaderJars = depset.New(depset.PREORDER, android.Paths{headerJar}, nil)
2816		completeStaticLibsImplementationJars = depset.New(depset.PREORDER, android.Paths{outputFile}, nil)
2817	}
2818
2819	implementationJarFile := outputFile
2820
2821	// merge implementation jar with resources if necessary
2822	if resourceJarFile != nil {
2823		jars := android.Paths{resourceJarFile, outputFile}
2824		combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
2825		TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{},
2826			false, nil, nil)
2827		outputFile = combinedJar
2828	}
2829
2830	// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource.
2831	// Also strip the relative path from the header output file so that the reuseImplementationJarAsHeaderJar check
2832	// in a module that depends on this module considers them equal.
2833	j.combinedHeaderFile = headerJar.WithoutRel()
2834	j.combinedImplementationFile = outputFile.WithoutRel()
2835
2836	j.maybeInstall(ctx, jarName, outputFile)
2837
2838	j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs)
2839
2840	if ctx.Config().UseTransitiveJarsInClasspath() {
2841		ctx.CheckbuildFile(localJars...)
2842	} else {
2843		ctx.CheckbuildFile(outputFile)
2844	}
2845
2846	if ctx.Device() {
2847		// Shared libraries deapexed from prebuilt apexes are no longer supported.
2848		// Set the dexJarBuildPath to a fake path.
2849		// This allows soong analysis pass, but will be an error during ninja execution if there are
2850		// any rdeps.
2851		ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
2852		if ai.ForPrebuiltApex {
2853			j.dexJarFile = makeDexJarPathFromPath(android.PathForModuleInstall(ctx, "intentionally_no_longer_supported"))
2854			j.initHiddenAPI(ctx, j.dexJarFile, outputFile, j.dexProperties.Uncompress_dex)
2855		} else if Bool(j.dexProperties.Compile_dex) {
2856			sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
2857			if sdkDep.invalidVersion {
2858				ctx.AddMissingDependencies(sdkDep.bootclasspath)
2859				ctx.AddMissingDependencies(sdkDep.java9Classpath)
2860			} else if sdkDep.useFiles {
2861				// sdkDep.jar is actually equivalent to turbine header.jar.
2862				flags.classpath = append(flags.classpath, sdkDep.jars...)
2863			}
2864
2865			// Dex compilation
2866
2867			j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
2868				ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), android.PathForModuleInstall(ctx, "framework", jarName))
2869			setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
2870			j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
2871
2872			var dexOutputFile android.Path
2873			dexParams := &compileDexParams{
2874				flags:         flags,
2875				sdkVersion:    j.SdkVersion(ctx),
2876				minSdkVersion: j.MinSdkVersion(ctx),
2877				classesJar:    outputFile,
2878				jarName:       jarName,
2879			}
2880
2881			dexOutputFile, _ = j.dexer.compileDex(ctx, dexParams)
2882			if ctx.Failed() {
2883				return
2884			}
2885			ctx.CheckbuildFile(dexOutputFile)
2886
2887			// Initialize the hiddenapi structure.
2888			j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), outputFile, j.dexProperties.Uncompress_dex)
2889
2890			// Encode hidden API flags in dex file.
2891			dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)
2892
2893			j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
2894			j.dexJarInstallFile = android.PathForModuleInstall(ctx, "framework", jarName)
2895		}
2896	}
2897
2898	android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
2899		HeaderJars:                             android.PathsIfNonNil(j.combinedHeaderFile),
2900		LocalHeaderJars:                        android.PathsIfNonNil(j.combinedHeaderFile),
2901		TransitiveLibsHeaderJarsForR8:          j.transitiveLibsHeaderJarsForR8,
2902		TransitiveStaticLibsHeaderJarsForR8:    j.transitiveStaticLibsHeaderJarsForR8,
2903		TransitiveStaticLibsHeaderJars:         completeStaticLibsHeaderJars,
2904		TransitiveStaticLibsImplementationJars: completeStaticLibsImplementationJars,
2905		TransitiveStaticLibsResourceJars:       completeStaticLibsResourceJars,
2906		ImplementationAndResourcesJars:         android.PathsIfNonNil(j.combinedImplementationFile),
2907		ImplementationJars:                     android.PathsIfNonNil(implementationJarFile.WithoutRel()),
2908		ResourceJars:                           android.PathsIfNonNil(resourceJarFile),
2909		AidlIncludeDirs:                        j.exportAidlIncludeDirs,
2910		StubsLinkType:                          j.stubsLinkType,
2911		// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
2912	})
2913
2914	ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, "")
2915	ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, ".jar")
2916}
2917
2918func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputFile android.Path) {
2919	if !Bool(j.properties.Installable) {
2920		return
2921	}
2922
2923	var installDir android.InstallPath
2924	if ctx.InstallInTestcases() {
2925		var archDir string
2926		if !ctx.Host() {
2927			archDir = ctx.DeviceConfig().DeviceArch()
2928		}
2929		installDir = android.PathForModuleInstall(ctx, ctx.ModuleName(), archDir)
2930	} else {
2931		installDir = android.PathForModuleInstall(ctx, "framework")
2932	}
2933	ctx.InstallFile(installDir, jarName, outputFile)
2934}
2935
2936func (j *Import) HeaderJars() android.Paths {
2937	return android.PathsIfNonNil(j.combinedHeaderFile)
2938}
2939
2940func (j *Import) ImplementationAndResourcesJars() android.Paths {
2941	return android.PathsIfNonNil(j.combinedImplementationFile)
2942}
2943
2944func (j *Import) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
2945	if j.dexJarFileErr != nil {
2946		ctx.ModuleErrorf(j.dexJarFileErr.Error())
2947	}
2948	return j.dexJarFile
2949}
2950
2951func (j *Import) DexJarInstallPath() android.Path {
2952	return j.dexJarInstallFile
2953}
2954
2955func (j *Import) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
2956	return j.classLoaderContexts
2957}
2958
2959var _ android.ApexModule = (*Import)(nil)
2960
2961// Implements android.ApexModule
2962func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
2963	return j.depIsInSameApex(ctx, dep)
2964}
2965
2966// Implements android.ApexModule
2967func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
2968	sdkVersion android.ApiLevel) error {
2969	sdkVersionSpec := j.SdkVersion(ctx)
2970	minSdkVersion := j.MinSdkVersion(ctx)
2971	if !minSdkVersion.Specified() {
2972		return fmt.Errorf("min_sdk_version is not specified")
2973	}
2974	// If the module is compiling against core (via sdk_version), skip comparison check.
2975	if sdkVersionSpec.Kind == android.SdkCore {
2976		return nil
2977	}
2978	if minSdkVersion.GreaterThan(sdkVersion) {
2979		return fmt.Errorf("newer SDK(%v)", minSdkVersion)
2980	}
2981	return nil
2982}
2983
2984// requiredFilesFromPrebuiltApexForImport returns information about the files that a java_import or
2985// java_sdk_library_import with the specified base module name requires to be exported from a
2986// prebuilt_apex/apex_set.
2987func requiredFilesFromPrebuiltApexForImport(name string, d *dexpreopter) []string {
2988	dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(name)
2989	// Add the dex implementation jar to the set of exported files.
2990	files := []string{
2991		dexJarFileApexRootRelative,
2992	}
2993	if BoolDefault(d.importDexpreoptProperties.Dex_preopt.Profile_guided, false) {
2994		files = append(files, dexJarFileApexRootRelative+".prof")
2995	}
2996	return files
2997}
2998
2999// ApexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for
3000// the java library with the specified name.
3001func ApexRootRelativePathToJavaLib(name string) string {
3002	return filepath.Join("javalib", name+".jar")
3003}
3004
3005var _ android.RequiredFilesFromPrebuiltApex = (*Import)(nil)
3006
3007func (j *Import) RequiredFilesFromPrebuiltApex(_ android.BaseModuleContext) []string {
3008	name := j.BaseModuleName()
3009	return requiredFilesFromPrebuiltApexForImport(name, &j.dexpreopter)
3010}
3011
3012func (j *Import) UseProfileGuidedDexpreopt() bool {
3013	return proptools.Bool(j.importDexpreoptProperties.Dex_preopt.Profile_guided)
3014}
3015
3016// Add compile time check for interface implementation
3017var _ android.IDEInfo = (*Import)(nil)
3018var _ android.IDECustomizedModuleName = (*Import)(nil)
3019
3020// Collect information for opening IDE project files in java/jdeps.go.
3021
3022func (j *Import) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
3023	dpInfo.Jars = append(dpInfo.Jars, j.combinedHeaderFile.String())
3024}
3025
3026func (j *Import) IDECustomizedModuleName() string {
3027	// TODO(b/113562217): Extract the base module name from the Import name, often the Import name
3028	// has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better
3029	// solution to get the Import name.
3030	return android.RemoveOptionalPrebuiltPrefix(j.Name())
3031}
3032
3033var _ android.PrebuiltInterface = (*Import)(nil)
3034
3035func (j *Import) IsInstallable() bool {
3036	return Bool(j.properties.Installable)
3037}
3038
3039var _ DexpreopterInterface = (*Import)(nil)
3040
3041// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module.
3042//
3043// By default, a java_import has a single variant that expects a `.jar` file containing `.class` files that were
3044// compiled against an Android classpath.
3045//
3046// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
3047// for host modules.
3048func ImportFactory() android.Module {
3049	module := &Import{}
3050
3051	module.AddProperties(
3052		&module.properties,
3053		&module.dexer.dexProperties,
3054		&module.importDexpreoptProperties,
3055	)
3056
3057	module.initModuleAndImport(module)
3058
3059	module.dexProperties.Optimize.EnabledByDefault = false
3060
3061	android.InitPrebuiltModule(module, &module.properties.Jars)
3062	android.InitApexModule(module)
3063	InitJavaModule(module, android.HostAndDeviceSupported)
3064	return module
3065}
3066
3067// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library_host
3068// module.
3069//
3070// A java_import_host has a single variant that expects a `.jar` file containing `.class` files that were
3071// compiled against a host bootclasspath.
3072func ImportFactoryHost() android.Module {
3073	module := &Import{}
3074
3075	module.AddProperties(&module.properties)
3076
3077	android.InitPrebuiltModule(module, &module.properties.Jars)
3078	android.InitApexModule(module)
3079	InitJavaModule(module, android.HostSupported)
3080	return module
3081}
3082
3083// dex_import module
3084
3085type DexImportProperties struct {
3086	Jars []string `android:"path"`
3087
3088	// set the name of the output
3089	Stem *string
3090}
3091
3092type DexImport struct {
3093	android.ModuleBase
3094	android.DefaultableModuleBase
3095	android.ApexModuleBase
3096	prebuilt android.Prebuilt
3097
3098	properties DexImportProperties
3099
3100	dexJarFile OptionalDexJarPath
3101
3102	dexpreopter
3103
3104	hideApexVariantFromMake bool
3105}
3106
3107func (j *DexImport) Prebuilt() *android.Prebuilt {
3108	return &j.prebuilt
3109}
3110
3111func (j *DexImport) PrebuiltSrcs() []string {
3112	return j.properties.Jars
3113}
3114
3115func (j *DexImport) Name() string {
3116	return j.prebuilt.Name(j.ModuleBase.Name())
3117}
3118
3119func (j *DexImport) Stem() string {
3120	return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
3121}
3122
3123func (a *DexImport) JacocoReportClassesFile() android.Path {
3124	return nil
3125}
3126
3127func (j *DexImport) IsInstallable() bool {
3128	return true
3129}
3130
3131func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
3132	if len(j.properties.Jars) != 1 {
3133		ctx.PropertyErrorf("jars", "exactly one jar must be provided")
3134	}
3135
3136	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
3137	if !apexInfo.IsForPlatform() {
3138		j.hideApexVariantFromMake = true
3139	}
3140
3141	j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
3142		ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
3143	j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &j.dexpreopter)
3144
3145	inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars")
3146	dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar")
3147
3148	if j.dexpreopter.uncompressedDex {
3149		rule := android.NewRuleBuilder(pctx, ctx)
3150
3151		temporary := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar.unaligned")
3152		rule.Temporary(temporary)
3153
3154		// use zip2zip to uncompress classes*.dex files
3155		rule.Command().
3156			BuiltTool("zip2zip").
3157			FlagWithInput("-i ", inputJar).
3158			FlagWithOutput("-o ", temporary).
3159			FlagWithArg("-0 ", "'classes*.dex'")
3160
3161		// use zipalign to align uncompressed classes*.dex files
3162		rule.Command().
3163			BuiltTool("zipalign").
3164			Flag("-f").
3165			Text("4").
3166			Input(temporary).
3167			Output(dexOutputFile)
3168
3169		rule.DeleteTemporaryFiles()
3170
3171		rule.Build("uncompress_dex", "uncompress dex")
3172	} else {
3173		ctx.Build(pctx, android.BuildParams{
3174			Rule:   android.Cp,
3175			Input:  inputJar,
3176			Output: dexOutputFile,
3177		})
3178	}
3179
3180	j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
3181
3182	j.dexpreopt(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), dexOutputFile)
3183
3184	if apexInfo.IsForPlatform() {
3185		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
3186			j.Stem()+".jar", dexOutputFile)
3187	}
3188}
3189
3190func (j *DexImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
3191	return j.dexJarFile
3192}
3193
3194var _ android.ApexModule = (*DexImport)(nil)
3195
3196// Implements android.ApexModule
3197func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
3198	sdkVersion android.ApiLevel) error {
3199	// we don't check prebuilt modules for sdk_version
3200	return nil
3201}
3202
3203// dex_import imports a `.jar` file containing classes.dex files.
3204//
3205// A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed
3206// to the device.
3207func DexImportFactory() android.Module {
3208	module := &DexImport{}
3209
3210	module.AddProperties(&module.properties)
3211
3212	android.InitPrebuiltModule(module, &module.properties.Jars)
3213	android.InitApexModule(module)
3214	InitJavaModule(module, android.DeviceSupported)
3215	return module
3216}
3217
3218// Defaults
3219type Defaults struct {
3220	android.ModuleBase
3221	android.DefaultsModuleBase
3222	android.ApexModuleBase
3223}
3224
3225// java_defaults provides a set of properties that can be inherited by other java or android modules.
3226//
3227// A module can use the properties from a java_defaults module using `defaults: ["defaults_module_name"]`.  Each
3228// property in the defaults module that exists in the depending module will be prepended to the depending module's
3229// value for that property.
3230//
3231// Example:
3232//
3233//	java_defaults {
3234//	    name: "example_defaults",
3235//	    srcs: ["common/**/*.java"],
3236//	    javacflags: ["-Xlint:all"],
3237//	    aaptflags: ["--auto-add-overlay"],
3238//	}
3239//
3240//	java_library {
3241//	    name: "example",
3242//	    defaults: ["example_defaults"],
3243//	    srcs: ["example/**/*.java"],
3244//	}
3245//
3246// is functionally identical to:
3247//
3248//	java_library {
3249//	    name: "example",
3250//	    srcs: [
3251//	        "common/**/*.java",
3252//	        "example/**/*.java",
3253//	    ],
3254//	    javacflags: ["-Xlint:all"],
3255//	}
3256func DefaultsFactory() android.Module {
3257	module := &Defaults{}
3258
3259	module.AddProperties(
3260		&CommonProperties{},
3261		&DeviceProperties{},
3262		&OverridableProperties{},
3263		&DexProperties{},
3264		&DexpreoptProperties{},
3265		&android.ProtoProperties{},
3266		&aaptProperties{},
3267		&androidLibraryProperties{},
3268		&appProperties{},
3269		&appTestProperties{},
3270		&overridableAppProperties{},
3271		&hostTestProperties{},
3272		&testProperties{},
3273		&ImportProperties{},
3274		&AARImportProperties{},
3275		&sdkLibraryProperties{},
3276		&commonToSdkLibraryAndImportProperties{},
3277		&DexImportProperties{},
3278		&android.ApexProperties{},
3279		&RuntimeResourceOverlayProperties{},
3280		&LintProperties{},
3281		&appTestHelperAppProperties{},
3282		&JavaApiLibraryProperties{},
3283		&bootclasspathFragmentProperties{},
3284		&SourceOnlyBootclasspathProperties{},
3285		&ravenwoodTestProperties{},
3286	)
3287
3288	android.InitDefaultsModule(module)
3289	return module
3290}
3291
3292func kytheExtractJavaFactory() android.Singleton {
3293	return &kytheExtractJavaSingleton{}
3294}
3295
3296type kytheExtractJavaSingleton struct {
3297}
3298
3299func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) {
3300	var xrefTargets android.Paths
3301	var xrefKotlinTargets android.Paths
3302	ctx.VisitAllModules(func(module android.Module) {
3303		if javaModule, ok := module.(xref); ok {
3304			xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...)
3305			xrefKotlinTargets = append(xrefKotlinTargets, javaModule.XrefKotlinFiles()...)
3306		}
3307	})
3308	// TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets
3309	if len(xrefTargets) > 0 {
3310		ctx.Phony("xref_java", xrefTargets...)
3311	}
3312	if len(xrefKotlinTargets) > 0 {
3313		ctx.Phony("xref_kotlin", xrefKotlinTargets...)
3314	}
3315}
3316
3317var Bool = proptools.Bool
3318var BoolDefault = proptools.BoolDefault
3319var String = proptools.String
3320var inList = android.InList[string]
3321
3322// Add class loader context (CLC) of a given dependency to the current CLC.
3323func addCLCFromDep(ctx android.ModuleContext, depModule android.Module,
3324	clcMap dexpreopt.ClassLoaderContextMap) {
3325
3326	dep, ok := depModule.(UsesLibraryDependency)
3327	if !ok {
3328		return
3329	}
3330
3331	depName := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(depModule))
3332
3333	var sdkLib *string
3334	if lib, ok := android.OtherModuleProvider(ctx, depModule, SdkLibraryInfoProvider); ok && lib.SharedLibrary {
3335		// A shared SDK library. This should be added as a top-level CLC element.
3336		sdkLib = &depName
3337	} else if lib, ok := depModule.(SdkLibraryComponentDependency); ok && lib.OptionalSdkLibraryImplementation() != nil {
3338		if depModule.Name() == proptools.String(lib.OptionalSdkLibraryImplementation())+".impl" {
3339			sdkLib = lib.OptionalSdkLibraryImplementation()
3340		}
3341	} else if ulib, ok := depModule.(ProvidesUsesLib); ok {
3342		// A non-SDK library disguised as an SDK library by the means of `provides_uses_lib`
3343		// property. This should be handled in the same way as a shared SDK library.
3344		sdkLib = ulib.ProvidesUsesLib()
3345	}
3346
3347	depTag := ctx.OtherModuleDependencyTag(depModule)
3348	if IsLibDepTag(depTag) {
3349		// Ok, propagate <uses-library> through non-static library dependencies.
3350	} else if tag, ok := depTag.(usesLibraryDependencyTag); ok && tag.sdkVersion == dexpreopt.AnySdkVersion {
3351		// Ok, propagate <uses-library> through non-compatibility <uses-library> dependencies.
3352	} else if depTag == staticLibTag {
3353		// Propagate <uses-library> through static library dependencies, unless it is a component
3354		// library (such as stubs). Component libraries have a dependency on their SDK library,
3355		// which should not be pulled just because of a static component library.
3356		if sdkLib != nil {
3357			return
3358		}
3359	} else {
3360		// Don't propagate <uses-library> for other dependency tags.
3361		return
3362	}
3363
3364	// If this is an SDK (or SDK-like) library, then it should be added as a node in the CLC tree,
3365	// and its CLC should be added as subtree of that node. Otherwise the library is not a
3366	// <uses_library> and should not be added to CLC, but the transitive <uses-library> dependencies
3367	// from its CLC should be added to the current CLC.
3368	if sdkLib != nil {
3369		optional := false
3370		if module, ok := ctx.Module().(ModuleWithUsesLibrary); ok {
3371			if android.InList(*sdkLib, module.UsesLibrary().usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) {
3372				optional = true
3373			}
3374		}
3375		clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, optional,
3376			dep.DexJarBuildPath(ctx).PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
3377	} else {
3378		clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
3379	}
3380}
3381
3382func addMissingOptionalUsesLibsFromDep(ctx android.ModuleContext, depModule android.Module,
3383	usesLibrary *usesLibrary) {
3384
3385	dep, ok := depModule.(ModuleWithUsesLibrary)
3386	if !ok {
3387		return
3388	}
3389
3390	for _, lib := range dep.UsesLibrary().usesLibraryProperties.Missing_optional_uses_libs {
3391		if !android.InList(lib, usesLibrary.usesLibraryProperties.Missing_optional_uses_libs) {
3392			usesLibrary.usesLibraryProperties.Missing_optional_uses_libs =
3393				append(usesLibrary.usesLibraryProperties.Missing_optional_uses_libs, lib)
3394		}
3395	}
3396}
3397
3398type JavaApiContributionImport struct {
3399	JavaApiContribution
3400
3401	prebuilt           android.Prebuilt
3402	prebuiltProperties javaApiContributionImportProperties
3403}
3404
3405type javaApiContributionImportProperties struct {
3406	// Name of the source soong module that gets shadowed by this prebuilt
3407	// If unspecified, follows the naming convention that the source module of
3408	// the prebuilt is Name() without "prebuilt_" prefix
3409	Source_module_name *string
3410
3411	// Non-nil if this java_import module was dynamically created by a java_sdk_library_import
3412	// The name is the undecorated name of the java_sdk_library as it appears in the blueprint file
3413	// (without any prebuilt_ prefix)
3414	Created_by_java_sdk_library_name *string `blueprint:"mutated"`
3415}
3416
3417func ApiContributionImportFactory() android.Module {
3418	module := &JavaApiContributionImport{}
3419	android.InitAndroidModule(module)
3420	android.InitDefaultableModule(module)
3421	android.InitPrebuiltModule(module, &[]string{""})
3422	module.AddProperties(&module.properties, &module.prebuiltProperties)
3423	module.AddProperties(&module.sdkLibraryComponentProperties)
3424	return module
3425}
3426
3427func (module *JavaApiContributionImport) Prebuilt() *android.Prebuilt {
3428	return &module.prebuilt
3429}
3430
3431func (module *JavaApiContributionImport) Name() string {
3432	return module.prebuilt.Name(module.ModuleBase.Name())
3433}
3434
3435func (j *JavaApiContributionImport) BaseModuleName() string {
3436	return proptools.StringDefault(j.prebuiltProperties.Source_module_name, j.ModuleBase.Name())
3437}
3438
3439func (j *JavaApiContributionImport) CreatedByJavaSdkLibraryName() *string {
3440	return j.prebuiltProperties.Created_by_java_sdk_library_name
3441}
3442
3443func (ap *JavaApiContributionImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
3444	ap.JavaApiContribution.GenerateAndroidBuildActions(ctx)
3445}
3446