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