• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2021 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
18	"encoding/gob"
19	"fmt"
20	"path/filepath"
21	"reflect"
22	"slices"
23	"strconv"
24	"strings"
25
26	"github.com/google/blueprint"
27	"github.com/google/blueprint/depset"
28	"github.com/google/blueprint/pathtools"
29	"github.com/google/blueprint/proptools"
30
31	"android/soong/android"
32	"android/soong/dexpreopt"
33	"android/soong/java/config"
34)
35
36// This file contains the definition and the implementation of the base module that most
37// source-based Java module structs embed.
38
39// TODO:
40// Autogenerated files:
41//  Renderscript
42// Post-jar passes:
43//  Proguard
44// Rmtypedefs
45// DroidDoc
46// Findbugs
47
48// Properties that are common to most Java modules, i.e. whether it's a host or device module.
49type CommonProperties struct {
50	// list of source files used to compile the Java module.  May be .java, .kt, .logtags, .proto,
51	// or .aidl files.
52	Srcs []string `android:"path,arch_variant"`
53
54	// list Kotlin of source files containing Kotlin code that should be treated as common code in
55	// a codebase that supports Kotlin multiplatform.  See
56	// https://kotlinlang.org/docs/reference/multiplatform.html.  May be only be .kt files.
57	Common_srcs []string `android:"path,arch_variant"`
58
59	// list of source files that should not be used to build the Java module.
60	// This is most useful in the arch/multilib variants to remove non-common files
61	Exclude_srcs []string `android:"path,arch_variant"`
62
63	// list of Kotlin source files that should excluded from the list of common_srcs.
64	Exclude_common_srcs []string `android:"path,arch_variant"`
65
66	// list of directories containing Java resources
67	Java_resource_dirs []string `android:"arch_variant"`
68
69	// list of directories that should be excluded from java_resource_dirs
70	Exclude_java_resource_dirs []string `android:"arch_variant"`
71
72	// list of files to use as Java resources
73	Java_resources proptools.Configurable[[]string] `android:"path,arch_variant"`
74
75	// list of files that should be excluded from java_resources and java_resource_dirs
76	Exclude_java_resources []string `android:"path,arch_variant"`
77
78	// Same as java_resources, but modules added here will use the device variant. Can be useful
79	// for making a host test that tests the contents of a device built app.
80	Device_common_java_resources proptools.Configurable[[]string] `android:"path_device_common"`
81
82	// Same as java_resources, but modules added here will use the device's os variant and the
83	// device's first architecture variant. Can be useful for making a host test that tests the
84	// contents of a native device built app.
85	Device_first_java_resources proptools.Configurable[[]string] `android:"path_device_first"`
86
87	// list of module-specific flags that will be used for javac compiles
88	Javacflags []string `android:"arch_variant"`
89
90	// list of module-specific flags that will be used for kotlinc compiles
91	Kotlincflags []string `android:"arch_variant"`
92
93	// Kotlin language version to target. Currently only 1.9 and 2 are supported.
94	// See kotlinc's `-language-version` flag.
95	Kotlin_lang_version *string
96
97	// list of java libraries that will be in the classpath
98	Libs []string `android:"arch_variant"`
99
100	// list of java libraries that will be compiled into the resulting jar
101	Static_libs proptools.Configurable[[]string] `android:"arch_variant"`
102
103	// manifest file to be included in resulting jar
104	Manifest *string `android:"path"`
105
106	// if not blank, run jarjar using the specified rules file
107	Jarjar_rules *string `android:"path,arch_variant"`
108
109	// java class names to rename with jarjar when a reverse dependency has a jarjar_prefix
110	// property.
111	Jarjar_rename []string
112
113	// if not blank, used as prefix to generate repackage rule
114	Jarjar_prefix *string
115
116	// Number of shards for jarjar. It needs to be an integer represented as a string.
117	// TODO(b/383559945) change it to int, once Configurable supports the type.
118	Jarjar_shards proptools.Configurable[string]
119
120	// If not blank, set the java version passed to javac as -source and -target
121	Java_version *string
122
123	// If set to true, allow this module to be dexed and installed on devices.  Has no
124	// effect on host modules, which are always considered installable.
125	Installable *bool
126
127	// If set to true, include sources used to compile the module in to the final jar
128	Include_srcs *bool
129
130	// If not empty, classes are restricted to the specified packages and their sub-packages.
131	// This restriction is checked after applying jarjar rules and including static libs.
132	Permitted_packages []string
133
134	// List of modules to use as annotation processors
135	Plugins []string
136
137	// List of modules to use as kotlin plugin
138	Kotlin_plugins []string
139
140	// List of modules to export to libraries that directly depend on this library as annotation
141	// processors.  Note that if the plugins set generates_api: true this will disable the turbine
142	// optimization on modules that depend on this module, which will reduce parallelism and cause
143	// more recompilation.
144	Exported_plugins []string
145
146	// The number of Java source entries each Javac instance can process
147	Javac_shard_size *int64
148
149	// Add host jdk tools.jar to bootclasspath
150	Use_tools_jar *bool
151
152	Openjdk9 struct {
153		// List of source files that should only be used when passing -source 1.9 or higher
154		Srcs []string `android:"path"`
155
156		// List of javac flags that should only be used when passing -source 1.9 or higher
157		Javacflags []string
158	}
159
160	// When compiling language level 9+ .java code in packages that are part of
161	// a system module, patch_module names the module that your sources and
162	// dependencies should be patched into. The Android runtime currently
163	// doesn't implement the JEP 261 module system so this option is only
164	// supported at compile time. It should only be needed to compile tests in
165	// packages that exist in libcore and which are inconvenient to move
166	// elsewhere.
167	Patch_module *string
168
169	Jacoco struct {
170		// List of classes to include for instrumentation with jacoco to collect coverage
171		// information at runtime when building with coverage enabled.  If unset defaults to all
172		// classes.
173		// Supports '*' as the last character of an entry in the list as a wildcard match.
174		// If preceded by '.' it matches all classes in the package and subpackages, otherwise
175		// it matches classes in the package that have the class name as a prefix.
176		Include_filter []string
177
178		// List of classes to exclude from instrumentation with jacoco to collect coverage
179		// information at runtime when building with coverage enabled.  Overrides classes selected
180		// by the include_filter property.
181		// Supports '*' as the last character of an entry in the list as a wildcard match.
182		// If preceded by '.' it matches all classes in the package and subpackages, otherwise
183		// it matches classes in the package that have the class name as a prefix.
184		Exclude_filter []string
185	}
186
187	Errorprone struct {
188		// List of javac flags that should only be used when running errorprone.
189		Javacflags []string
190
191		// List of java_plugin modules that provide extra errorprone checks.
192		Extra_check_modules []string
193
194		// This property can be in 3 states. When set to true, errorprone will
195		// be run during the regular build. When set to false, errorprone will
196		// never be run. When unset, errorprone will be run when the RUN_ERROR_PRONE
197		// environment variable is true. Setting this to false will improve build
198		// performance more than adding -XepDisableAllChecks in javacflags.
199		Enabled *bool
200	}
201
202	Proto struct {
203		// List of extra options that will be passed to the proto generator.
204		Output_params []string
205	}
206
207	// If true, then jacocoagent is automatically added as a libs dependency so that
208	// r8 will not strip instrumentation classes out of dexed libraries.
209	Instrument bool `blueprint:"mutated"`
210	// If true, then the module supports statically including the jacocoagent
211	// into the library.
212	Supports_static_instrumentation bool `blueprint:"mutated"`
213
214	// List of files to include in the META-INF/services folder of the resulting jar.
215	Services []string `android:"path,arch_variant"`
216
217	// If true, package the kotlin stdlib into the jar.  Defaults to true.
218	Static_kotlin_stdlib *bool `android:"arch_variant"`
219
220	// A list of java_library instances that provide additional hiddenapi annotations for the library.
221	Hiddenapi_additional_annotations []string
222
223	// Additional srcJars tacked in by GeneratedJavaLibraryModule
224	Generated_srcjars []android.Path `android:"mutated"`
225
226	// intermediate aconfig cache file tacked in by GeneratedJavaLibraryModule
227	Aconfig_Cache_files []android.Path `android:"mutated"`
228
229	// If true, then only the headers are built and not the implementation jar.
230	Headers_only *bool
231
232	// A list of files or dependencies to make available to the build sandbox. This is
233	// useful if source files are symlinks, the targets of the symlinks must be listed here.
234	// Note that currently not all actions implemented by android_apps are sandboxed, so you
235	// may only see this being necessary in lint builds.
236	Compile_data []string `android:"path"`
237
238	// Property signifying whether the module compiles stubs or not.
239	// Should be set to true when srcs of this module are stub files.
240	// This property does not need to be set to true when the module depends on
241	// the stubs via libs, but should be set to true when the module depends on
242	// the stubs via static libs.
243	Is_stubs_module *bool
244
245	Ravenizer struct {
246		// If true, enable the "Ravenizer" tool on the output jar.
247		// "Ravenizer" is a tool for Ravenwood tests, but it can also be enabled on other kinds
248		// of java targets.
249		Enabled *bool
250
251		// If true, the "Ravenizer" tool will remove all Mockito and DexMaker
252		// classes from the output jar.
253		Strip_mockito *bool
254	}
255
256	// Contributing api surface of the stub module. Is not visible to bp modules, and should
257	// only be set for stub submodules generated by the java_sdk_library
258	Stub_contributing_api *string `blueprint:"mutated"`
259
260	// If true, enable the "ApiMapper" tool on the output jar. "ApiMapper" is a tool to inject
261	// bytecode to log API calls.
262	ApiMapper bool `blueprint:"mutated"`
263}
264
265// Properties that are specific to device modules. Host module factories should not add these when
266// constructing a new module.
267type DeviceProperties struct {
268	// If not blank, set to the version of the sdk to compile against.
269	// Defaults to an empty string, which compiles the module against the private platform APIs.
270	// Values are of one of the following forms:
271	// 1) numerical API level, "current", "none", or "core_platform"
272	// 2) An SDK kind with an API level: "<sdk kind>_<API level>"
273	// See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds.
274	// If the SDK kind is empty, it will be set to public.
275	Sdk_version *string
276
277	// if not blank, set the maximum version of the sdk that the compiled artifacts will run against.
278	// Defaults to empty string "". See sdk_version for possible values.
279	Max_sdk_version *string
280
281	// if not blank, set the maxSdkVersion properties of permission and uses-permission tags.
282	// Defaults to empty string "". See sdk_version for possible values.
283	Replace_max_sdk_version_placeholder *string
284
285	// if not blank, set the targetSdkVersion in the AndroidManifest.xml.
286	// Defaults to sdk_version if not set. See sdk_version for possible values.
287	Target_sdk_version *string
288
289	// Whether to compile against the platform APIs instead of an SDK.
290	// If true, then sdk_version must be empty. The value of this field
291	// is ignored when module's type isn't android_app, android_test, or android_test_helper_app.
292	Platform_apis *bool
293
294	Aidl struct {
295		// Top level directories to pass to aidl tool
296		Include_dirs []string
297
298		// Directories rooted at the Android.bp file to pass to aidl tool
299		Local_include_dirs []string
300
301		// directories that should be added as include directories for any aidl sources of modules
302		// that depend on this module, as well as to aidl for this module.
303		Export_include_dirs []string
304
305		// whether to generate traces (for systrace) for this interface
306		Generate_traces *bool
307
308		// whether to generate Binder#GetTransaction name method.
309		Generate_get_transaction_name *bool
310
311		// whether all interfaces should be annotated with required permissions.
312		Enforce_permissions *bool
313
314		// allowlist for interfaces that (temporarily) do not require annotation for permissions.
315		Enforce_permissions_exceptions []string `android:"path"`
316
317		// list of flags that will be passed to the AIDL compiler
318		Flags []string
319	}
320
321	// If true, export a copy of the module as a -hostdex module for host testing.
322	Hostdex *bool
323
324	Target struct {
325		Hostdex struct {
326			// Additional required dependencies to add to -hostdex modules.
327			Required []string
328		}
329	}
330
331	// When targeting 1.9 and above, override the modules to use with --system,
332	// otherwise provides defaults libraries to add to the bootclasspath.
333	System_modules *string
334
335	IsSDKLibrary bool `blueprint:"mutated"`
336
337	// If true, generate the signature file of APK Signing Scheme V4, along side the signed APK file.
338	// Defaults to false.
339	V4_signature *bool
340
341	// Only for libraries created by a sysprop_library module, SyspropPublicStub is the name of the
342	// public stubs library.
343	SyspropPublicStub string `blueprint:"mutated"`
344
345	HiddenAPIPackageProperties
346	HiddenAPIFlagFileProperties
347}
348
349// Properties that can be overridden by overriding module (e.g. override_android_app)
350type OverridableProperties struct {
351	// set the name of the output. If not set, `name` is used.
352	// To override a module with this property set, overriding module might need to set this as well.
353	// Otherwise, both the overridden and the overriding modules will have the same output name, which
354	// can cause the duplicate output error.
355	Stem *string
356
357	// if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
358	// Defaults to sdk_version if not set. See sdk_version for possible values.
359	Min_sdk_version *string
360}
361
362// Functionality common to Module and Import
363//
364// It is embedded in Module so its functionality can be used by methods in Module
365// but it is currently only initialized by Import and Library.
366type embeddableInModuleAndImport struct {
367
368	// Functionality related to this being used as a component of a java_sdk_library.
369	EmbeddableSdkLibraryComponent
370}
371
372func (e *embeddableInModuleAndImport) initModuleAndImport(module android.Module) {
373	e.initSdkLibraryComponent(module)
374}
375
376// Module/Import's OutgoingDepIsInSameApex(...) delegates to this method.
377//
378// This cannot implement OutgoingDepIsInSameApex(...) directly as that leads to ambiguity with
379// the one provided by ApexModuleBase.
380func depIsInSameApex(tag blueprint.DependencyTag) bool {
381	// dependencies other than the static linkage are all considered crossing APEX boundary
382	if tag == staticLibTag {
383		return true
384	}
385	return false
386}
387
388// OptionalDexJarPath can be either unset, hold a valid path to a dex jar file,
389// or an invalid path describing the reason it is invalid.
390//
391// It is unset if a dex jar isn't applicable, i.e. no build rule has been
392// requested to create one.
393//
394// If a dex jar has been requested to be built then it is set, and it may be
395// either a valid android.Path, or invalid with a reason message. The latter
396// happens if the source that should produce the dex file isn't able to.
397//
398// E.g. it is invalid with a reason message if there is a prebuilt APEX that
399// could produce the dex jar through a deapexer module, but the APEX isn't
400// installable so doing so wouldn't be safe.
401type OptionalDexJarPath struct {
402	isSet bool
403	path  android.OptionalPath
404}
405
406// IsSet returns true if a path has been set, either invalid or valid.
407func (o OptionalDexJarPath) IsSet() bool {
408	return o.isSet
409}
410
411// Valid returns true if there is a path that is valid.
412func (o OptionalDexJarPath) Valid() bool {
413	return o.isSet && o.path.Valid()
414}
415
416// Path returns the valid path, or panics if it's either not set or is invalid.
417func (o OptionalDexJarPath) Path() android.Path {
418	if !o.isSet {
419		panic("path isn't set")
420	}
421	return o.path.Path()
422}
423
424// PathOrNil returns the path if it's set and valid, or else nil.
425func (o OptionalDexJarPath) PathOrNil() android.Path {
426	if o.Valid() {
427		return o.Path()
428	}
429	return nil
430}
431
432// InvalidReason returns the reason for an invalid path, which is never "". It
433// returns "" for an unset or valid path.
434func (o OptionalDexJarPath) InvalidReason() string {
435	if !o.isSet {
436		return ""
437	}
438	return o.path.InvalidReason()
439}
440
441func (o OptionalDexJarPath) String() string {
442	if !o.isSet {
443		return "<unset>"
444	}
445	return o.path.String()
446}
447
448// makeUnsetDexJarPath returns an unset OptionalDexJarPath.
449func makeUnsetDexJarPath() OptionalDexJarPath {
450	return OptionalDexJarPath{isSet: false}
451}
452
453// makeDexJarPathFromOptionalPath returns an OptionalDexJarPath that is set with
454// the given OptionalPath, which may be valid or invalid.
455func makeDexJarPathFromOptionalPath(path android.OptionalPath) OptionalDexJarPath {
456	return OptionalDexJarPath{isSet: true, path: path}
457}
458
459// makeDexJarPathFromPath returns an OptionalDexJarPath that is set with the
460// valid given path. It returns an unset OptionalDexJarPath if the given path is
461// nil.
462func makeDexJarPathFromPath(path android.Path) OptionalDexJarPath {
463	if path == nil {
464		return makeUnsetDexJarPath()
465	}
466	return makeDexJarPathFromOptionalPath(android.OptionalPathForPath(path))
467}
468
469// Module contains the properties and members used by all java module types
470type Module struct {
471	android.ModuleBase
472	android.DefaultableModuleBase
473	android.ApexModuleBase
474
475	// Functionality common to Module and Import.
476	embeddableInModuleAndImport
477
478	properties       CommonProperties
479	protoProperties  android.ProtoProperties
480	deviceProperties DeviceProperties
481
482	overridableProperties OverridableProperties
483	sourceProperties      android.SourceProperties
484
485	// jar file containing header classes including static library dependencies, suitable for
486	// inserting into the bootclasspath/classpath of another compile
487	headerJarFile android.Path
488
489	// jar file containing implementation classes including static library dependencies but no
490	// resources
491	implementationJarFile android.Path
492
493	// args and dependencies to package source files into a srcjar
494	srcJarArgs []string
495	srcJarDeps android.Paths
496
497	// the source files of this module and all its static dependencies
498	transitiveSrcFiles depset.DepSet[android.Path]
499
500	// jar file containing implementation classes and resources including static library
501	// dependencies
502	implementationAndResourcesJar android.Path
503
504	// output file containing classes.dex and resources
505	dexJarFile OptionalDexJarPath
506
507	// output file containing uninstrumented classes that will be instrumented by jacoco
508	jacocoReportClassesFile android.Path
509
510	// output file of the module, which may be a classes jar or a dex jar
511	outputFile       android.Path
512	extraOutputFiles android.Paths
513
514	exportAidlIncludeDirs     android.Paths
515	ignoredAidlPermissionList android.Paths
516
517	logtagsSrcs android.Paths
518
519	// installed file for binary dependency
520	installFile android.Path
521
522	// installed file for hostdex copy
523	hostdexInstallFile android.InstallPath
524
525	// list of unique .java and .kt source files
526	uniqueSrcFiles android.Paths
527
528	// list of srcjars that was passed to javac
529	compiledSrcJars android.Paths
530
531	// manifest file to use instead of properties.Manifest
532	overrideManifest android.OptionalPath
533
534	// list of plugins that this java module is exporting
535	exportedPluginJars android.Paths
536
537	// list of plugins that this java module is exporting
538	exportedPluginClasses []string
539
540	// if true, the exported plugins generate API and require disabling turbine.
541	exportedDisableTurbine bool
542
543	// list of source files, collected from srcFiles with unique java and all kt files,
544	// will be used by android.IDEInfo struct
545	expandIDEInfoCompiledSrcs []string
546
547	// expanded Jarjar_rules
548	expandJarjarRules android.Path
549
550	// jarjar rule for inherited jarjar rules
551	repackageJarjarRules android.Path
552
553	// Extra files generated by the module type to be added as java resources.
554	extraResources android.Paths
555
556	hiddenAPI
557	dexer
558	dexpreopter
559	usesLibrary
560	linter
561
562	// list of the xref extraction files
563	kytheFiles       android.Paths
564	kytheKotlinFiles android.Paths
565
566	hideApexVariantFromMake bool
567
568	sdkVersion    android.SdkSpec
569	minSdkVersion android.ApiLevel
570	maxSdkVersion android.ApiLevel
571
572	sourceExtensions []string
573
574	annoSrcJars android.Paths
575
576	// output file name based on Stem property.
577	// This should be set in every ModuleWithStem's GenerateAndroidBuildActions
578	// or the module should override Stem().
579	stem string
580
581	// Values that will be set in the JarJarProvider data for jarjar repackaging,
582	// and merged with our dependencies' rules.
583	jarjarRenameRules map[string]string
584
585	stubsLinkType StubsLinkType
586
587	// Paths to the aconfig intermediate cache files that are provided by the
588	// java_aconfig_library or java_library modules that are statically linked
589	// to this module. Does not contain cache files from all transitive dependencies.
590	aconfigCacheFiles android.Paths
591
592	// List of soong module dependencies required to compile the current module.
593	// This information is printed out to `Dependencies` field in module_bp_java_deps.json
594	compileDepNames []string
595
596	ravenizer struct {
597		enabled bool
598	}
599}
600
601var _ android.InstallableModule = (*Module)(nil)
602
603// To satisfy the InstallableModule interface
604func (j *Module) StaticDependencyTags() []blueprint.DependencyTag {
605	return []blueprint.DependencyTag{staticLibTag}
606}
607
608// To satisfy the InstallableModule interface
609func (j *Module) DynamicDependencyTags() []blueprint.DependencyTag {
610	return []blueprint.DependencyTag{libTag, sdkLibTag, bootClasspathTag, systemModulesTag,
611		instrumentationForTag, java9LibTag}
612}
613
614// Overrides android.ModuleBase.InstallInProduct()
615func (j *Module) InstallInProduct() bool {
616	return j.ProductSpecific()
617}
618
619var _ android.StubsAvailableModule = (*Module)(nil)
620
621// To safisfy the StubsAvailableModule interface
622func (j *Module) IsStubsModule() bool {
623	return proptools.Bool(j.properties.Is_stubs_module)
624}
625
626func CheckStableSdkVersion(ctx android.BaseModuleContext, module android.ModuleProxy) error {
627	if info, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
628		if info.SdkVersion.Stable() {
629			return nil
630		}
631		if info.SdkVersion.Kind == android.SdkCorePlatform {
632			if useLegacyCorePlatformApi(ctx, android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).BaseModuleName) {
633				return fmt.Errorf("non stable SDK %v - uses legacy core platform", info.SdkVersion)
634			} else {
635				// Treat stable core platform as stable.
636				return nil
637			}
638		} else {
639			return fmt.Errorf("non stable SDK %v", info.SdkVersion)
640		}
641	}
642
643	return nil
644}
645
646// checkSdkVersions enforces restrictions around SDK dependencies.
647func (j *Module) checkSdkVersions(ctx android.ModuleContext) {
648	if j.RequiresStableAPIs(ctx) {
649		if sc, ok := ctx.Module().(android.SdkContext); ok {
650			if !sc.SdkVersion(ctx).Specified() {
651				ctx.PropertyErrorf("sdk_version",
652					"sdk_version must have a value when the module is located at vendor or product(only if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is set).")
653			}
654		}
655	}
656
657	// Make sure this module doesn't statically link to modules with lower-ranked SDK link type.
658	// See rank() for details.
659	ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
660		tag := ctx.OtherModuleDependencyTag(module)
661		libInfo, isJavaLibrary := android.OtherModuleProvider(ctx, module, JavaLibraryInfoProvider)
662		_, isAndroidLibrary := android.OtherModuleProvider(ctx, module, AndroidLibraryInfoProvider)
663		_, isJavaAconfigLibrary := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider)
664		// Exclude java_aconfig_library modules to maintain consistency with existing behavior.
665		if (isJavaLibrary && !libInfo.Prebuilt && !isJavaAconfigLibrary) || isAndroidLibrary {
666			// TODO(satayev): cover other types as well, e.g. imports
667			switch tag {
668			case bootClasspathTag, sdkLibTag, libTag, staticLibTag, java9LibTag:
669				j.checkSdkLinkType(ctx, module)
670			}
671		}
672	})
673}
674
675func (j *Module) checkPlatformAPI(ctx android.ModuleContext) {
676	if sc, ok := ctx.Module().(android.SdkContext); ok {
677		usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis)
678		sdkVersionSpecified := sc.SdkVersion(ctx).Specified()
679		if usePlatformAPI && sdkVersionSpecified {
680			ctx.PropertyErrorf("platform_apis", "This module has conflicting settings. sdk_version is not empty, which means this module cannot use platform APIs. However platform_apis is set to true.")
681		} else if !usePlatformAPI && !sdkVersionSpecified {
682			ctx.PropertyErrorf("platform_apis", "This module has conflicting settings. sdk_version is empty, which means that this module is build against platform APIs. However platform_apis is not set to true")
683		}
684
685	}
686}
687
688func (j *Module) checkHeadersOnly(ctx android.ModuleContext) {
689	if _, ok := ctx.Module().(android.SdkContext); ok {
690		headersOnly := proptools.Bool(j.properties.Headers_only)
691		installable := proptools.Bool(j.properties.Installable)
692
693		if headersOnly && installable {
694			ctx.PropertyErrorf("headers_only", "This module has conflicting settings. headers_only is true which, which means this module doesn't generate an implementation jar. However installable is set to true.")
695		}
696	}
697}
698
699func (j *Module) addHostProperties() {
700	j.AddProperties(
701		&j.properties,
702		&j.overridableProperties,
703		&j.protoProperties,
704		&j.usesLibraryProperties,
705	)
706}
707
708func (j *Module) addHostAndDeviceProperties() {
709	j.addHostProperties()
710	j.AddProperties(
711		&j.deviceProperties,
712		&j.dexer.dexProperties,
713		&j.dexpreoptProperties,
714		&j.linter.properties,
715	)
716}
717
718// provideHiddenAPIPropertyInfo populates a HiddenAPIPropertyInfo from hidden API properties and
719// makes it available through the hiddenAPIPropertyInfoProvider.
720func (j *Module) provideHiddenAPIPropertyInfo(ctx android.ModuleContext) {
721	hiddenAPIInfo := newHiddenAPIPropertyInfo()
722
723	// Populate with flag file paths from the properties.
724	hiddenAPIInfo.extractFlagFilesFromProperties(ctx, &j.deviceProperties.HiddenAPIFlagFileProperties)
725
726	// Populate with package rules from the properties.
727	hiddenAPIInfo.extractPackageRulesFromProperties(&j.deviceProperties.HiddenAPIPackageProperties)
728
729	android.SetProvider(ctx, hiddenAPIPropertyInfoProvider, hiddenAPIInfo)
730}
731
732// helper method for java modules to set OutputFilesProvider
733func setOutputFiles(ctx android.ModuleContext, m Module) {
734	ctx.SetOutputFiles(append(android.PathsIfNonNil(m.outputFile), m.extraOutputFiles...), "")
735	ctx.SetOutputFiles(android.PathsIfNonNil(m.outputFile), android.DefaultDistTag)
736	ctx.SetOutputFiles(android.PathsIfNonNil(m.implementationAndResourcesJar), ".jar")
737	ctx.SetOutputFiles(android.PathsIfNonNil(m.headerJarFile), ".hjar")
738	if m.dexer.proguardDictionary.Valid() {
739		ctx.SetOutputFiles(android.Paths{m.dexer.proguardDictionary.Path()}, ".proguard_map")
740	}
741	ctx.SetOutputFiles(m.properties.Generated_srcjars, ".generated_srcjars")
742}
743
744func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
745	initJavaModule(module, hod, false)
746}
747
748func InitJavaModuleMultiTargets(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
749	initJavaModule(module, hod, true)
750}
751
752func initJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported, multiTargets bool) {
753	multilib := android.MultilibCommon
754	if multiTargets {
755		android.InitAndroidMultiTargetsArchModule(module, hod, multilib)
756	} else {
757		android.InitAndroidArchModule(module, hod, multilib)
758	}
759	android.InitDefaultableModule(module)
760}
761
762func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool {
763	return j.properties.Instrument &&
764		ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") &&
765		ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir())
766}
767
768func (j *Module) shouldApiMapper() bool {
769	return j.properties.ApiMapper
770}
771
772func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool {
773	return j.properties.Supports_static_instrumentation &&
774		j.shouldInstrument(ctx) &&
775		(ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_STATIC") ||
776			ctx.Config().UnbundledBuild())
777}
778
779func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool {
780	// Force enable the instrumentation for java code that is built for APEXes ...
781	// except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent
782	// doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true.
783	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
784	isJacocoAgent := ctx.ModuleName() == "jacocoagent"
785
786	compileDex := Bool(j.dexProperties.Compile_dex) || Bool(j.properties.Installable)
787	if compileDex && !isJacocoAgent && !apexInfo.IsForPlatform() {
788		if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
789			return true
790		} else if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
791			return true
792		}
793	}
794	return false
795}
796
797func (j *Module) setInstrument(value bool) {
798	j.properties.Instrument = value
799}
800
801func (j *Module) setApiMapper(value bool) {
802	j.properties.ApiMapper = value
803}
804
805func (j *Module) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
806	return android.SdkSpecFrom(ctx, String(j.deviceProperties.Sdk_version))
807}
808
809func (j *Module) SystemModules() string {
810	return proptools.String(j.deviceProperties.System_modules)
811}
812
813func (j *Module) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
814	if j.overridableProperties.Min_sdk_version != nil {
815		return android.ApiLevelFrom(ctx, *j.overridableProperties.Min_sdk_version)
816	}
817	return j.SdkVersion(ctx).ApiLevel
818}
819
820func (j *Module) GetDeviceProperties() *DeviceProperties {
821	return &j.deviceProperties
822}
823
824func (j *Module) MaxSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
825	if j.deviceProperties.Max_sdk_version != nil {
826		return android.ApiLevelFrom(ctx, *j.deviceProperties.Max_sdk_version)
827	}
828	// Default is PrivateApiLevel
829	return android.SdkSpecPrivate.ApiLevel
830}
831
832func (j *Module) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
833	if j.deviceProperties.Replace_max_sdk_version_placeholder != nil {
834		return android.ApiLevelFrom(ctx, *j.deviceProperties.Replace_max_sdk_version_placeholder)
835	}
836	// Default is PrivateApiLevel
837	return android.SdkSpecPrivate.ApiLevel
838}
839
840func (j *Module) MinSdkVersionString() string {
841	return j.minSdkVersion.String()
842}
843
844func (j *Module) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
845	if j.deviceProperties.Target_sdk_version != nil {
846		return android.ApiLevelFrom(ctx, *j.deviceProperties.Target_sdk_version)
847	}
848	return j.SdkVersion(ctx).ApiLevel
849}
850
851func (j *Module) AvailableFor(what string) bool {
852	return android.CheckAvailableForApex(what, j.ApexAvailableFor())
853}
854
855func (j *Module) ApexAvailableFor() []string {
856	list := j.ApexModuleBase.ApexAvailable()
857	if Bool(j.deviceProperties.Hostdex) {
858		// Exception: for hostdex: true libraries, the platform variant is created
859		// even if it's not marked as available to platform. In that case, the platform
860		// variant is used only for the hostdex and not installed to the device.
861		list = append(list, android.AvailableToPlatform)
862	}
863	return android.FirstUniqueStrings(list)
864}
865
866func (j *Module) staticLibs(ctx android.BaseModuleContext) []string {
867	return j.properties.Static_libs.GetOrDefault(ctx, nil)
868}
869
870func (j *Module) deps(ctx android.BottomUpMutatorContext) {
871	if ctx.Device() {
872		j.linter.deps(ctx)
873
874		sdkDeps(ctx, android.SdkContext(j), j.dexer)
875
876		if j.deviceProperties.SyspropPublicStub != "" {
877			// This is a sysprop implementation library that has a corresponding sysprop public
878			// stubs library, and a dependency on it so that dependencies on the implementation can
879			// be forwarded to the public stubs library when necessary.
880			ctx.AddVariationDependencies(nil, syspropPublicStubDepTag, j.deviceProperties.SyspropPublicStub)
881		}
882	}
883
884	libDeps := ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
885
886	ctx.AddVariationDependencies(nil, staticLibTag, j.staticLibs(ctx)...)
887
888	// Add dependency on libraries that provide additional hidden api annotations.
889	ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...)
890
891	// Add dependency on (soft) downstream libs from which to trace references during optimization.
892	traceRefs := j.dexProperties.Optimize.Trace_references_from.GetOrDefault(ctx, []string{})
893	ctx.AddVariationDependencies(nil, traceReferencesTag, traceRefs...)
894
895	// For library dependencies that are component libraries (like stubs), add the implementation
896	// as a dependency (dexpreopt needs to be against the implementation library, not stubs).
897	for _, dep := range libDeps {
898		if dep != nil {
899			if component, ok := dep.(SdkLibraryComponentDependency); ok {
900				if lib := component.OptionalSdkLibraryImplementation(); lib != nil {
901					// Add library as optional if it's one of the optional compatibility libs or it's
902					// explicitly listed in the optional_uses_libs property.
903					tag := usesLibReqTag
904					if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) ||
905						android.InList(*lib, j.usesLibrary.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) {
906						tag = usesLibOptTag
907					}
908					ctx.AddVariationDependencies(nil, tag, *lib)
909				}
910			}
911		}
912	}
913
914	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...)
915	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), kotlinPluginTag, j.properties.Kotlin_plugins...)
916	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), errorpronePluginTag, j.properties.Errorprone.Extra_check_modules...)
917	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...)
918
919	android.ProtoDeps(ctx, &j.protoProperties)
920	if j.hasSrcExt(".proto") {
921		protoDeps(ctx, &j.protoProperties)
922	}
923
924	if j.hasSrcExt(".kt") {
925		// TODO(ccross): move this to a mutator pass that can tell if generated sources contain
926		// Kotlin files
927		tag := staticLibTag
928		if !BoolDefault(j.properties.Static_kotlin_stdlib, true) {
929			tag = libTag
930		}
931		ctx.AddVariationDependencies(nil, tag,
932			"kotlin-stdlib", "kotlin-stdlib-jdk7", "kotlin-stdlib-jdk8", "kotlin-annotations")
933	}
934
935	// Framework libraries need special handling in static coverage builds: they should not have
936	// static dependency on jacoco, otherwise there would be multiple conflicting definitions of
937	// the same jacoco classes coming from different bootclasspath jars.
938	if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
939		if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
940			j.properties.Instrument = true
941		}
942	} else if j.shouldInstrumentStatic(ctx) {
943		ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
944	}
945
946	if j.useCompose(ctx) {
947		ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), kotlinPluginTag,
948			"kotlin-compose-compiler-plugin")
949	}
950}
951
952func hasSrcExt(srcs []string, ext string) bool {
953	for _, src := range srcs {
954		if filepath.Ext(src) == ext {
955			return true
956		}
957	}
958
959	return false
960}
961
962func (j *Module) hasSrcExt(ext string) bool {
963	return hasSrcExt(j.properties.Srcs, ext)
964}
965
966func (j *Module) individualAidlFlags(ctx android.ModuleContext, aidlFile android.Path) string {
967	var flags string
968
969	if Bool(j.deviceProperties.Aidl.Enforce_permissions) {
970		if !android.InList(aidlFile.String(), j.ignoredAidlPermissionList.Strings()) {
971			flags = "-Wmissing-permission-annotation -Werror"
972		}
973	}
974	return flags
975}
976
977func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
978	aidlIncludeDirs android.Paths, aidlSrcs android.Paths) (string, android.Paths) {
979
980	aidlIncludes := android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Local_include_dirs)
981	aidlIncludes = append(aidlIncludes,
982		android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)...)
983	aidlIncludes = append(aidlIncludes,
984		android.PathsForSource(ctx, j.deviceProperties.Aidl.Include_dirs)...)
985
986	var flags []string
987	var deps android.Paths
988	var includeDirs android.Paths
989
990	flags = append(flags, j.deviceProperties.Aidl.Flags...)
991
992	if aidlPreprocess.Valid() {
993		flags = append(flags, "-p"+aidlPreprocess.String())
994		deps = append(deps, aidlPreprocess.Path())
995	} else if len(aidlIncludeDirs) > 0 {
996		includeDirs = append(includeDirs, aidlIncludeDirs...)
997	}
998
999	if len(j.exportAidlIncludeDirs) > 0 {
1000		includeDirs = append(includeDirs, j.exportAidlIncludeDirs...)
1001	}
1002
1003	if len(aidlIncludes) > 0 {
1004		includeDirs = append(includeDirs, aidlIncludes...)
1005	}
1006
1007	includeDirs = append(includeDirs, android.PathForModuleSrc(ctx))
1008	if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
1009		includeDirs = append(includeDirs, src.Path())
1010	}
1011	flags = append(flags, android.JoinWithPrefix(includeDirs.Strings(), "-I"))
1012	// add flags for dirs containing AIDL srcs that haven't been specified yet
1013	flags = append(flags, genAidlIncludeFlags(ctx, aidlSrcs, includeDirs))
1014
1015	sdkVersion := (j.SdkVersion(ctx)).Kind
1016	defaultTrace := ((sdkVersion == android.SdkSystemServer) || (sdkVersion == android.SdkCore) || (sdkVersion == android.SdkCorePlatform) || (sdkVersion == android.SdkModule) || (sdkVersion == android.SdkSystem))
1017	if proptools.BoolDefault(j.deviceProperties.Aidl.Generate_traces, defaultTrace) {
1018		flags = append(flags, "-t")
1019	}
1020
1021	if Bool(j.deviceProperties.Aidl.Generate_get_transaction_name) {
1022		flags = append(flags, "--transaction_names")
1023	}
1024
1025	if Bool(j.deviceProperties.Aidl.Enforce_permissions) {
1026		exceptions := j.deviceProperties.Aidl.Enforce_permissions_exceptions
1027		j.ignoredAidlPermissionList = android.PathsForModuleSrcExcludes(ctx, exceptions, nil)
1028	}
1029
1030	aidlMinSdkVersion := j.MinSdkVersion(ctx).String()
1031	flags = append(flags, "--min_sdk_version="+aidlMinSdkVersion)
1032
1033	return strings.Join(flags, " "), deps
1034}
1035
1036func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags {
1037
1038	var flags javaBuilderFlags
1039
1040	// javaVersion flag.
1041	flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), android.SdkContext(j))
1042
1043	epEnabled := j.properties.Errorprone.Enabled
1044	if (ctx.Config().RunErrorProne() && epEnabled == nil) || Bool(epEnabled) {
1045		if config.ErrorProneClasspath == nil && !ctx.Config().RunningInsideUnitTest() {
1046			ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
1047		}
1048
1049		errorProneFlags := []string{
1050			"-Xplugin:ErrorProne",
1051			"${config.ErrorProneChecks}",
1052		}
1053		errorProneFlags = append(errorProneFlags, j.properties.Errorprone.Javacflags...)
1054
1055		flags.errorProneExtraJavacFlags = "${config.ErrorProneHeapFlags} ${config.ErrorProneFlags} " +
1056			"'" + strings.Join(errorProneFlags, " ") + "'"
1057		flags.errorProneProcessorPath = classpath(android.PathsForSource(ctx, config.ErrorProneClasspath))
1058	}
1059
1060	// classpath
1061	flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...)
1062	flags.classpath = append(flags.classpath, deps.classpath...)
1063	flags.dexClasspath = append(flags.dexClasspath, deps.dexClasspath...)
1064	flags.java9Classpath = append(flags.java9Classpath, deps.java9Classpath...)
1065	flags.processorPath = append(flags.processorPath, deps.processorPath...)
1066	flags.errorProneProcessorPath = append(flags.errorProneProcessorPath, deps.errorProneProcessorPath...)
1067
1068	flags.processors = append(flags.processors, deps.processorClasses...)
1069	flags.processors = android.FirstUniqueStrings(flags.processors)
1070
1071	if len(flags.bootClasspath) == 0 && ctx.Host() && !flags.javaVersion.usesJavaModules() &&
1072		decodeSdkDep(ctx, android.SdkContext(j)).hasStandardLibs() {
1073		// Give host-side tools a version of OpenJDK's standard libraries
1074		// close to what they're targeting. As of Dec 2017, AOSP is only
1075		// bundling OpenJDK 8 and 9, so nothing < 8 is available.
1076		//
1077		// When building with OpenJDK 8, the following should have no
1078		// effect since those jars would be available by default.
1079		//
1080		// When building with OpenJDK 9 but targeting a version < 1.8,
1081		// putting them on the bootclasspath means that:
1082		// a) code can't (accidentally) refer to OpenJDK 9 specific APIs
1083		// b) references to existing APIs are not reinterpreted in an
1084		//    OpenJDK 9-specific way, eg. calls to subclasses of
1085		//    java.nio.Buffer as in http://b/70862583
1086		java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1087		flags.bootClasspath = append(flags.bootClasspath,
1088			android.PathForSource(ctx, java8Home, "jre/lib/jce.jar"),
1089			android.PathForSource(ctx, java8Home, "jre/lib/rt.jar"))
1090		if Bool(j.properties.Use_tools_jar) {
1091			flags.bootClasspath = append(flags.bootClasspath,
1092				android.PathForSource(ctx, java8Home, "lib/tools.jar"))
1093		}
1094	}
1095
1096	// systemModules
1097	flags.systemModules = deps.systemModules
1098
1099	return flags
1100}
1101
1102func (j *Module) collectJavacFlags(
1103	ctx android.ModuleContext, flags javaBuilderFlags, srcFiles android.Paths) javaBuilderFlags {
1104	// javac flags.
1105	javacFlags := j.properties.Javacflags
1106	var needsDebugInfo bool
1107
1108	needsDebugInfo = false
1109	for _, flag := range javacFlags {
1110		if strings.HasPrefix(flag, "-g") {
1111			needsDebugInfo = true
1112		}
1113	}
1114
1115	if ctx.Config().MinimizeJavaDebugInfo() && !ctx.Host() && !needsDebugInfo {
1116		// For non-host binaries, override the -g flag passed globally to remove
1117		// local variable debug info to reduce disk and memory usage.
1118		javacFlags = append(javacFlags, "-g:source,lines")
1119	}
1120	javacFlags = append(javacFlags, "-Xlint:-dep-ann")
1121
1122	if flags.javaVersion.usesJavaModules() {
1123		javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
1124	} else if len(j.properties.Openjdk9.Javacflags) > 0 {
1125		// java version defaults higher than openjdk 9, these conditionals should no longer be necessary
1126		ctx.PropertyErrorf("openjdk9.javacflags", "JDK version defaults to higher than 9")
1127	}
1128
1129	if flags.javaVersion.usesJavaModules() {
1130		if j.properties.Patch_module != nil {
1131			// Manually specify build directory in case it is not under the repo root.
1132			// (javac doesn't seem to expand into symbolic links when searching for patch-module targets, so
1133			// just adding a symlink under the root doesn't help.)
1134			patchPaths := []string{".", ctx.Config().SoongOutDir()}
1135
1136			classPath := flags.classpath.FormJavaClassPath("")
1137			if classPath != "" {
1138				patchPaths = append(patchPaths, classPath)
1139			}
1140			javacFlags = append(
1141				javacFlags,
1142				"--patch-module="+String(j.properties.Patch_module)+"="+strings.Join(patchPaths, ":"))
1143		}
1144	}
1145
1146	if len(javacFlags) > 0 {
1147		// optimization.
1148		ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
1149		flags.javacFlags = "$javacFlags"
1150	}
1151
1152	return flags
1153}
1154
1155func (j *Module) AddJSONData(d *map[string]interface{}) {
1156	(&j.ModuleBase).AddJSONData(d)
1157	(*d)["Java"] = map[string]interface{}{
1158		"SourceExtensions": j.sourceExtensions,
1159	}
1160
1161}
1162
1163func (j *Module) addGeneratedSrcJars(path android.Path) {
1164	j.properties.Generated_srcjars = append(j.properties.Generated_srcjars, path)
1165}
1166
1167func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars, extraDepCombinedJars android.Paths) *JavaInfo {
1168	// Auto-propagating jarjar rules
1169	jarjarProviderData := j.collectJarJarRules(ctx)
1170	if jarjarProviderData != nil {
1171		android.SetProvider(ctx, JarJarProvider, *jarjarProviderData)
1172		text := getJarJarRuleText(jarjarProviderData)
1173		if text != "" {
1174			ruleTextFile := android.PathForModuleOut(ctx, "repackaged-jarjar", "repackaging.txt")
1175			android.WriteFileRule(ctx, ruleTextFile, text)
1176			j.repackageJarjarRules = ruleTextFile
1177		}
1178	}
1179
1180	j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)
1181
1182	// Only override the original value if explicitly set
1183	if j.properties.Ravenizer.Enabled != nil {
1184		j.ravenizer.enabled = *j.properties.Ravenizer.Enabled
1185	}
1186
1187	deps := j.collectDeps(ctx)
1188	flags := j.collectBuilderFlags(ctx, deps)
1189
1190	if flags.javaVersion.usesJavaModules() {
1191		j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
1192	} else if len(j.properties.Openjdk9.Javacflags) > 0 {
1193		// java version defaults higher than openjdk 9, these conditionals should no longer be necessary
1194		ctx.PropertyErrorf("openjdk9.srcs", "JDK version defaults to higher than 9")
1195	}
1196
1197	srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
1198	j.sourceExtensions = []string{}
1199	for _, ext := range []string{".kt", ".proto", ".aidl", ".java", ".logtags"} {
1200		if hasSrcExt(srcFiles.Strings(), ext) {
1201			j.sourceExtensions = append(j.sourceExtensions, ext)
1202		}
1203	}
1204	if hasSrcExt(srcFiles.Strings(), ".proto") {
1205		flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags)
1206	}
1207
1208	kotlinCommonSrcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Common_srcs, j.properties.Exclude_common_srcs)
1209	if len(kotlinCommonSrcFiles.FilterOutByExt(".kt")) > 0 {
1210		ctx.PropertyErrorf("common_srcs", "common_srcs must be .kt files")
1211	}
1212
1213	aidlSrcs := srcFiles.FilterByExt(".aidl")
1214	flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs, aidlSrcs)
1215
1216	nonGeneratedSrcJars := srcFiles.FilterByExt(".srcjar")
1217	srcFiles = j.genSources(ctx, srcFiles, flags)
1218
1219	// Collect javac flags only after computing the full set of srcFiles to
1220	// ensure that the --patch-module lookup paths are complete.
1221	flags = j.collectJavacFlags(ctx, flags, srcFiles)
1222
1223	srcJars := srcFiles.FilterByExt(".srcjar")
1224	srcJars = append(srcJars, deps.srcJars...)
1225	srcJars = append(srcJars, extraSrcJars...)
1226	srcJars = append(srcJars, j.properties.Generated_srcjars...)
1227	srcFiles = srcFiles.FilterOutByExt(".srcjar")
1228
1229	if j.properties.Jarjar_rules != nil {
1230		j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
1231	}
1232
1233	jarName := j.Stem() + ".jar"
1234
1235	var uniqueJavaFiles android.Paths
1236	set := make(map[string]bool)
1237	for _, v := range srcFiles.FilterByExt(".java") {
1238		if _, found := set[v.String()]; !found {
1239			set[v.String()] = true
1240			uniqueJavaFiles = append(uniqueJavaFiles, v)
1241		}
1242	}
1243	var uniqueKtFiles android.Paths
1244	for _, v := range srcFiles.FilterByExt(".kt") {
1245		if _, found := set[v.String()]; !found {
1246			set[v.String()] = true
1247			uniqueKtFiles = append(uniqueKtFiles, v)
1248		}
1249	}
1250
1251	var uniqueSrcFiles android.Paths
1252	uniqueSrcFiles = append(uniqueSrcFiles, uniqueJavaFiles...)
1253	uniqueSrcFiles = append(uniqueSrcFiles, uniqueKtFiles...)
1254	j.uniqueSrcFiles = uniqueSrcFiles
1255
1256	// We don't currently run annotation processors in turbine, which means we can't use turbine
1257	// generated header jars when an annotation processor that generates API is enabled.  One
1258	// exception (handled further below) is when kotlin sources are enabled, in which case turbine
1259	//  is used to run all of the annotation processors.
1260	disableTurbine := deps.disableTurbine
1261
1262	// Collect .java and .kt files for AIDEGen
1263	j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...)
1264
1265	var kotlinHeaderJars android.Paths
1266
1267	// Prepend extraClasspathJars to classpath so that the resource processor R.jar comes before
1268	// any dependencies so that it can override any non-final R classes from dependencies with the
1269	// final R classes from the app.
1270	flags.classpath = append(android.CopyOf(extraClasspathJars), flags.classpath...)
1271
1272	j.aconfigCacheFiles = append(deps.aconfigProtoFiles, j.properties.Aconfig_Cache_files...)
1273
1274	var localImplementationJars android.Paths
1275
1276	// If compiling headers then compile them and skip the rest
1277	if proptools.Bool(j.properties.Headers_only) {
1278		if srcFiles.HasExt(".kt") {
1279			ctx.ModuleErrorf("Compiling headers_only with .kt not supported")
1280		}
1281		if ctx.Config().IsEnvFalse("TURBINE_ENABLED") || disableTurbine {
1282			ctx.ModuleErrorf("headers_only is enabled but Turbine is disabled.")
1283		}
1284
1285		transitiveStaticLibsHeaderJars := deps.transitiveStaticLibsHeaderJars
1286
1287		localHeaderJars, combinedHeaderJarFile := j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName,
1288			extraCombinedJars)
1289
1290		combinedHeaderJarFile, jarjared := j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine", false)
1291		if jarjared {
1292			localHeaderJars = android.Paths{combinedHeaderJarFile}
1293			transitiveStaticLibsHeaderJars = nil
1294		}
1295		combinedHeaderJarFile, repackaged := j.repackageFlagsIfNecessary(ctx, combinedHeaderJarFile, jarName, "repackage-turbine")
1296		if repackaged {
1297			localHeaderJars = android.Paths{combinedHeaderJarFile}
1298			transitiveStaticLibsHeaderJars = nil
1299		}
1300		if ctx.Failed() {
1301			return nil
1302		}
1303		j.headerJarFile = combinedHeaderJarFile
1304
1305		if len(localHeaderJars) > 0 {
1306			ctx.CheckbuildFile(localHeaderJars...)
1307		} else {
1308			// There are no local sources or resources in this module, so there is nothing to checkbuild.
1309			ctx.UncheckedModule()
1310		}
1311
1312		j.outputFile = j.headerJarFile
1313		return &JavaInfo{
1314			HeaderJars:                          android.PathsIfNonNil(j.headerJarFile),
1315			LocalHeaderJars:                     localHeaderJars,
1316			TransitiveStaticLibsHeaderJars:      depset.New(depset.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars),
1317			TransitiveLibsHeaderJarsForR8:       j.transitiveLibsHeaderJarsForR8,
1318			TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
1319			AidlIncludeDirs:                     j.exportAidlIncludeDirs,
1320			ExportedPlugins:                     j.exportedPluginJars,
1321			ExportedPluginClasses:               j.exportedPluginClasses,
1322			ExportedPluginDisableTurbine:        j.exportedDisableTurbine,
1323			StubsLinkType:                       j.stubsLinkType,
1324			AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles,
1325			SdkVersion:                          j.SdkVersion(ctx),
1326		}
1327	}
1328
1329	if srcFiles.HasExt(".kt") {
1330		// When using kotlin sources turbine is used to generate annotation processor sources,
1331		// including for annotation processors that generate API, so we can use turbine for
1332		// java sources too.
1333		disableTurbine = false
1334
1335		// user defined kotlin flags.
1336		kotlincFlags := j.properties.Kotlincflags
1337		CheckKotlincFlags(ctx, kotlincFlags)
1338
1339		// Available kotlin versions can be found at
1340		// https://github.com/JetBrains/kotlin/blob/master/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt#L560
1341		// in the `LanguageVersion` class.
1342		// For now, avoid targeting language versions directly, as we'd like to kee our source
1343		// code version aligned as much as possible. Ideally, after defaulting to "2", we
1344		// can remove the "1.9" option entirely, or at least make it emit a warning.
1345		kotlin_default_lang_version := "1.9"
1346		if build_flag_lang_version, ok := ctx.Config().GetBuildFlag("RELEASE_KOTLIN_LANG_VERSION"); ok {
1347			kotlin_default_lang_version = build_flag_lang_version
1348		}
1349		kotlin_lang_version := proptools.StringDefault(j.properties.Kotlin_lang_version, kotlin_default_lang_version)
1350		switch kotlin_lang_version {
1351		case "1.9":
1352			kotlincFlags = append(kotlincFlags, "-language-version 1.9")
1353		case "2":
1354			kotlincFlags = append(kotlincFlags, "-Xsuppress-version-warnings", "-Xconsistent-data-class-copy-visibility")
1355		default:
1356			ctx.PropertyErrorf("kotlin_lang_version", "Must be one of `1.9` or `2`")
1357		}
1358
1359		// Workaround for KT-46512
1360		kotlincFlags = append(kotlincFlags, "-Xsam-conversions=class")
1361
1362		// If there are kotlin files, compile them first but pass all the kotlin and java files
1363		// kotlinc will use the java files to resolve types referenced by the kotlin files, but
1364		// won't emit any classes for them.
1365		kotlincFlags = append(kotlincFlags, "-no-stdlib")
1366		if ctx.Device() {
1367			kotlincFlags = append(kotlincFlags, "-no-jdk")
1368		}
1369
1370		for _, plugin := range deps.kotlinPlugins {
1371			kotlincFlags = append(kotlincFlags, "-Xplugin="+plugin.String())
1372		}
1373		flags.kotlincDeps = append(flags.kotlincDeps, deps.kotlinPlugins...)
1374
1375		if len(kotlincFlags) > 0 {
1376			// optimization.
1377			ctx.Variable(pctx, "kotlincFlags", strings.Join(kotlincFlags, " "))
1378			flags.kotlincFlags += "$kotlincFlags"
1379		}
1380
1381		// Collect common .kt files for AIDEGen
1382		j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...)
1383
1384		flags.kotlincClasspath = append(flags.kotlincClasspath, flags.bootClasspath...)
1385		flags.kotlincClasspath = append(flags.kotlincClasspath, flags.classpath...)
1386
1387		if len(flags.processorPath) > 0 {
1388			// Use kapt for annotation processing
1389			kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar")
1390			kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar")
1391			kotlinKapt(ctx, kaptSrcJar, kaptResJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
1392			srcJars = append(srcJars, kaptSrcJar)
1393			localImplementationJars = append(localImplementationJars, kaptResJar)
1394			// Disable annotation processing in javac, it's already been handled by kapt
1395			flags.processorPath = nil
1396			flags.processors = nil
1397		}
1398
1399		kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
1400		kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName)
1401		j.kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
1402		if ctx.Failed() {
1403			return nil
1404		}
1405
1406		kotlinJarPath, _ := j.repackageFlagsIfNecessary(ctx, kotlinJar, jarName, "kotlinc")
1407
1408		// Make javac rule depend on the kotlinc rule
1409		flags.classpath = append(classpath{kotlinHeaderJar}, flags.classpath...)
1410
1411		localImplementationJars = append(localImplementationJars, kotlinJarPath)
1412
1413		kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar)
1414	}
1415
1416	j.compiledSrcJars = srcJars
1417
1418	transitiveStaticLibsHeaderJars := deps.transitiveStaticLibsHeaderJars
1419
1420	enableSharding := false
1421	var localHeaderJars android.Paths
1422	var shardingHeaderJars android.Paths
1423	var repackagedHeaderJarFile android.Path
1424	if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !disableTurbine {
1425		if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
1426			enableSharding = true
1427			// Formerly, there was a check here that prevented annotation processors
1428			// from being used when sharding was enabled, as some annotation processors
1429			// do not function correctly in sharded environments. It was removed to
1430			// allow for the use of annotation processors that do function correctly
1431			// with sharding enabled. See: b/77284273.
1432		}
1433		extraJars := slices.Clone(kotlinHeaderJars)
1434		extraJars = append(extraJars, extraCombinedJars...)
1435		var combinedHeaderJarFile android.Path
1436		localHeaderJars, combinedHeaderJarFile = j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars)
1437		shardingHeaderJars = localHeaderJars
1438
1439		var jarjared bool
1440		j.headerJarFile, jarjared = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine", false)
1441		if jarjared {
1442			// jarjar modifies transitive static dependencies, use the combined header jar and drop the transitive
1443			// static libs header jars.
1444			localHeaderJars = android.Paths{j.headerJarFile}
1445			transitiveStaticLibsHeaderJars = nil
1446		}
1447		var repackaged bool
1448		repackagedHeaderJarFile, repackaged = j.repackageFlagsIfNecessary(ctx, j.headerJarFile, jarName, "turbine")
1449		if repackaged {
1450			// repackage modifies transitive static dependencies, use the combined header jar and drop the transitive
1451			// static libs header jars.
1452			// TODO(b/356688296): this shouldn't export both the unmodified and repackaged header jars
1453			localHeaderJars = android.Paths{j.headerJarFile, repackagedHeaderJarFile}
1454			transitiveStaticLibsHeaderJars = nil
1455		}
1456	}
1457	if len(uniqueJavaFiles) > 0 || len(srcJars) > 0 {
1458		hasErrorproneableFiles := false
1459		for _, ext := range j.sourceExtensions {
1460			if ext != ".proto" && ext != ".aidl" {
1461				// Skip running errorprone on pure proto or pure aidl modules. Some modules take a long time to
1462				// compile, and it's not useful to have warnings on these generated sources.
1463				hasErrorproneableFiles = true
1464				break
1465			}
1466		}
1467		var extraJarDeps android.Paths
1468		if Bool(j.properties.Errorprone.Enabled) {
1469			// If error-prone is enabled, enable errorprone flags on the regular
1470			// build.
1471			flags = enableErrorproneFlags(flags)
1472		} else if hasErrorproneableFiles && ctx.Config().RunErrorProne() && j.properties.Errorprone.Enabled == nil {
1473			if ctx.Config().RunErrorProneInline() {
1474				// On CI, we're not going to toggle back/forth between errorprone and non-errorprone
1475				// builds, so it's faster if we don't compile the module twice and instead always
1476				// compile the module with errorprone.
1477				flags = enableErrorproneFlags(flags)
1478			} else {
1479				// Otherwise, if the RUN_ERROR_PRONE environment variable is set, create
1480				// a new jar file just for compiling with the errorprone compiler to.
1481				// This is because we don't want to cause the java files to get completely
1482				// rebuilt every time the state of the RUN_ERROR_PRONE variable changes.
1483				// We also don't want to run this if errorprone is enabled by default for
1484				// this module, or else we could have duplicated errorprone messages.
1485				errorproneFlags := enableErrorproneFlags(flags)
1486				errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
1487				errorproneAnnoSrcJar := android.PathForModuleOut(ctx, "errorprone", "anno.srcjar")
1488
1489				transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneAnnoSrcJar, errorproneFlags, nil,
1490					"errorprone", "errorprone")
1491
1492				extraJarDeps = append(extraJarDeps, errorprone)
1493			}
1494		}
1495
1496		if enableSharding {
1497			if len(shardingHeaderJars) > 0 {
1498				flags.classpath = append(classpath(slices.Clone(shardingHeaderJars)), flags.classpath...)
1499			}
1500			shardSize := int(*(j.properties.Javac_shard_size))
1501			var shardSrcs []android.Paths
1502			if len(uniqueJavaFiles) > 0 {
1503				shardSrcs = android.ShardPaths(uniqueJavaFiles, shardSize)
1504				for idx, shardSrc := range shardSrcs {
1505					classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
1506						nil, flags, extraJarDeps)
1507					classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(idx))
1508					localImplementationJars = append(localImplementationJars, classes)
1509				}
1510			}
1511			// Assume approximately 5 sources per srcjar.
1512			// For framework-minus-apex in AOSP at the time this was written, there are 266 srcjars, with a mean
1513			// of 5.8 sources per srcjar, but a median of 1, a standard deviation of 10, and a max of 48 source files.
1514			if len(srcJars) > 0 {
1515				startIdx := len(shardSrcs)
1516				shardSrcJarsList := android.ShardPaths(srcJars, shardSize/5)
1517				for idx, shardSrcJars := range shardSrcJarsList {
1518					classes := j.compileJavaClasses(ctx, jarName, startIdx+idx,
1519						nil, shardSrcJars, flags, extraJarDeps)
1520					classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(startIdx+idx))
1521					localImplementationJars = append(localImplementationJars, classes)
1522				}
1523			}
1524		} else {
1525			classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
1526			classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac")
1527			localImplementationJars = append(localImplementationJars, classes)
1528		}
1529		if ctx.Failed() {
1530			return nil
1531		}
1532	}
1533
1534	localImplementationJars = append(localImplementationJars, extraCombinedJars...)
1535
1536	j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles
1537
1538	var includeSrcJar android.WritablePath
1539	if Bool(j.properties.Include_srcs) {
1540		includeSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+".srcjar")
1541		TransformResourcesToJar(ctx, includeSrcJar, j.srcJarArgs, j.srcJarDeps)
1542	}
1543
1544	dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs,
1545		j.properties.Exclude_java_resource_dirs, j.properties.Exclude_java_resources)
1546	fileArgs, fileDeps := ResourceFilesToJarArgs(ctx, j.properties.Java_resources.GetOrDefault(ctx, nil), j.properties.Exclude_java_resources)
1547	fileArgs2, fileDeps2 := ResourceFilesToJarArgs(ctx, j.properties.Device_common_java_resources.GetOrDefault(ctx, nil), nil)
1548	fileArgs3, fileDeps3 := ResourceFilesToJarArgs(ctx, j.properties.Device_first_java_resources.GetOrDefault(ctx, nil), nil)
1549	fileArgs = slices.Concat(fileArgs, fileArgs2, fileArgs3)
1550	fileDeps = slices.Concat(fileDeps, fileDeps2, fileDeps3)
1551	extraArgs, extraDeps := resourcePathsToJarArgs(j.extraResources), j.extraResources
1552
1553	var resArgs []string
1554	var resDeps android.Paths
1555
1556	resArgs = append(resArgs, dirArgs...)
1557	resDeps = append(resDeps, dirDeps...)
1558
1559	resArgs = append(resArgs, fileArgs...)
1560	resDeps = append(resDeps, fileDeps...)
1561
1562	resArgs = append(resArgs, extraArgs...)
1563	resDeps = append(resDeps, extraDeps...)
1564
1565	var localResourceJars android.Paths
1566	if len(resArgs) > 0 {
1567		resourceJar := android.PathForModuleOut(ctx, "res", jarName)
1568		TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
1569		if ctx.Failed() {
1570			return nil
1571		}
1572		localResourceJars = append(localResourceJars, resourceJar)
1573	}
1574
1575	if Bool(j.properties.Include_srcs) {
1576		localResourceJars = append(localResourceJars, includeSrcJar)
1577	}
1578
1579	services := android.PathsForModuleSrc(ctx, j.properties.Services)
1580	if len(services) > 0 {
1581		servicesJar := android.PathForModuleOut(ctx, "services", jarName)
1582		var zipargs []string
1583		for _, file := range services {
1584			serviceFile := file.String()
1585			zipargs = append(zipargs, "-C", filepath.Dir(serviceFile), "-f", serviceFile)
1586		}
1587		rule := zip
1588		args := map[string]string{
1589			"jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "),
1590		}
1591		if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ZIP") {
1592			rule = zipRE
1593			args["implicits"] = strings.Join(services.Strings(), ",")
1594		}
1595		ctx.Build(pctx, android.BuildParams{
1596			Rule:      rule,
1597			Output:    servicesJar,
1598			Implicits: services,
1599			Args:      args,
1600		})
1601		localResourceJars = append(localResourceJars, servicesJar)
1602	}
1603
1604	completeStaticLibsResourceJars := depset.New(depset.PREORDER, localResourceJars, deps.transitiveStaticLibsResourceJars)
1605
1606	var combinedResourceJar android.Path
1607	resourceJars := completeStaticLibsResourceJars.ToList()
1608	if len(resourceJars) == 1 {
1609		combinedResourceJar = resourceJars[0]
1610	} else if len(resourceJars) > 0 {
1611		combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
1612		TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{},
1613			false, nil, nil)
1614		combinedResourceJar = combinedJar
1615	}
1616
1617	manifest := j.overrideManifest
1618	if !manifest.Valid() && j.properties.Manifest != nil {
1619		manifest = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *j.properties.Manifest))
1620	}
1621
1622	// Combine the classes built from sources, any manifests, and any static libraries into
1623	// classes.jar. If there is only one input jar this step will be skipped.
1624	var outputFile android.Path
1625
1626	completeStaticLibsImplementationJars := depset.New(depset.PREORDER, localImplementationJars, deps.transitiveStaticLibsImplementationJars)
1627
1628	jars := completeStaticLibsImplementationJars.ToList()
1629
1630	jars = append(jars, extraDepCombinedJars...)
1631
1632	if len(jars) == 1 && !manifest.Valid() {
1633		// Optimization: skip the combine step as there is nothing to do
1634		// TODO(ccross): this leaves any module-info.class files, but those should only come from
1635		// prebuilt dependencies until we support modules in the platform build, so there shouldn't be
1636		// any if len(extraJars) == 0.
1637
1638		// moduleStubLinkType determines if the module is the TopLevelStubLibrary generated
1639		// from sdk_library. The TopLevelStubLibrary contains only one static lib,
1640		// either with .from-source or .from-text suffix.
1641		// outputFile should be agnostic to the build configuration,
1642		// thus copy the single input static lib in order to prevent the static lib from being exposed
1643		// to the copy rules.
1644		if stub, _ := moduleStubLinkType(j); stub {
1645			copiedJar := android.PathForModuleOut(ctx, "combined", jarName)
1646			ctx.Build(pctx, android.BuildParams{
1647				Rule:   android.Cp,
1648				Input:  jars[0],
1649				Output: copiedJar,
1650			})
1651			completeStaticLibsImplementationJars = depset.New(depset.PREORDER, android.Paths{copiedJar}, nil)
1652			outputFile = copiedJar
1653		} else {
1654			outputFile = jars[0]
1655		}
1656	} else {
1657		combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
1658		TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest,
1659			false, nil, nil)
1660		outputFile = combinedJar
1661	}
1662
1663	// jarjar implementation jar if necessary
1664	jarjarFile, jarjarred := j.jarjarIfNecessary(ctx, outputFile, jarName, "", true)
1665	if jarjarred {
1666		localImplementationJars = android.Paths{jarjarFile}
1667		completeStaticLibsImplementationJars = depset.New(depset.PREORDER, localImplementationJars, nil)
1668	}
1669	outputFile = jarjarFile
1670
1671	// jarjar resource jar if necessary
1672	if combinedResourceJar != nil {
1673		resourceJarJarFile, jarjarred := j.jarjarIfNecessary(ctx, combinedResourceJar, jarName, "resource", false)
1674		combinedResourceJar = resourceJarJarFile
1675		if jarjarred {
1676			localResourceJars = android.Paths{resourceJarJarFile}
1677			completeStaticLibsResourceJars = depset.New(depset.PREORDER, localResourceJars, nil)
1678		}
1679	}
1680
1681	if ctx.Failed() {
1682		return nil
1683	}
1684
1685	if j.ravenizer.enabled {
1686		ravenizerInput := outputFile
1687		ravenizerOutput := android.PathForModuleOut(ctx, "ravenizer", "", jarName)
1688		ravenizerArgs := ""
1689		if proptools.Bool(j.properties.Ravenizer.Strip_mockito) {
1690			ravenizerArgs = "--strip-mockito"
1691		}
1692		TransformRavenizer(ctx, ravenizerOutput, ravenizerInput, ravenizerArgs)
1693		outputFile = ravenizerOutput
1694		localImplementationJars = android.Paths{ravenizerOutput}
1695		completeStaticLibsImplementationJars = depset.New(depset.PREORDER, localImplementationJars, nil)
1696		if combinedResourceJar != nil {
1697			ravenizerInput = combinedResourceJar
1698			ravenizerOutput = android.PathForModuleOut(ctx, "ravenizer", "resources", jarName)
1699			TransformRavenizer(ctx, ravenizerOutput, ravenizerInput, ravenizerArgs)
1700			combinedResourceJar = ravenizerOutput
1701			localResourceJars = android.Paths{ravenizerOutput}
1702			completeStaticLibsResourceJars = depset.New(depset.PREORDER, localResourceJars, nil)
1703		}
1704	}
1705
1706	if j.shouldApiMapper() {
1707		inputFile := outputFile
1708		apiMapperFile := android.PathForModuleOut(ctx, "apimapper", jarName)
1709		ctx.Build(pctx, android.BuildParams{
1710			Rule:        apimapper,
1711			Description: "apimapper",
1712			Input:       inputFile,
1713			Output:      apiMapperFile,
1714		})
1715		outputFile = apiMapperFile
1716		localImplementationJars = android.Paths{apiMapperFile}
1717		completeStaticLibsImplementationJars = depset.New(depset.PREORDER, localImplementationJars, nil)
1718	}
1719
1720	// Check package restrictions if necessary.
1721	if len(j.properties.Permitted_packages) > 0 {
1722		// Time stamp file created by the package check rule.
1723		pkgckFile := android.PathForModuleOut(ctx, "package-check.stamp")
1724
1725		// Create a rule to copy the output jar to another path and add a validate dependency that
1726		// will check that the jar only contains the permitted packages. The new location will become
1727		// the output file of this module.
1728		inputFile := outputFile
1729		packageCheckOutputFile := android.PathForModuleOut(ctx, "package-check", jarName)
1730		ctx.Build(pctx, android.BuildParams{
1731			Rule:   android.Cp,
1732			Input:  inputFile,
1733			Output: packageCheckOutputFile,
1734			// Make sure that any dependency on the output file will cause ninja to run the package check
1735			// rule.
1736			Validation: pkgckFile,
1737		})
1738		outputFile = packageCheckOutputFile
1739		localImplementationJars = android.Paths{packageCheckOutputFile}
1740		completeStaticLibsImplementationJars = depset.New(depset.PREORDER, localImplementationJars, nil)
1741
1742		// Check packages and create a timestamp file when complete.
1743		CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages)
1744
1745		if ctx.Failed() {
1746			return nil
1747		}
1748	}
1749
1750	j.implementationJarFile = outputFile
1751	if j.headerJarFile == nil {
1752		// If this module couldn't generate a header jar (for example due to api generating annotation processors)
1753		// then use the implementation jar.  Run it through zip2zip first to remove any files in META-INF/services
1754		// so that javac on modules that depend on this module don't pick up annotation processors (which may be
1755		// missing their implementations) from META-INF/services/javax.annotation.processing.Processor.
1756		headerJarFile := android.PathForModuleOut(ctx, "javac-header", jarName)
1757		convertImplementationJarToHeaderJar(ctx, j.implementationJarFile, headerJarFile)
1758		j.headerJarFile = headerJarFile
1759		if len(localImplementationJars) == 1 {
1760			localHeaderJarFile := android.PathForModuleOut(ctx, "local-javac-header", jarName)
1761			convertImplementationJarToHeaderJar(ctx, localImplementationJars[0], localHeaderJarFile)
1762			localHeaderJars = append(localHeaderJars, localHeaderJarFile)
1763		} else {
1764			localHeaderJars = append(localHeaderJars, headerJarFile)
1765		}
1766	}
1767
1768	// enforce syntax check to jacoco filters for any build (http://b/183622051)
1769	specs := j.jacocoModuleToZipCommand(ctx)
1770	if ctx.Failed() {
1771		return nil
1772	}
1773
1774	completeStaticLibsImplementationJarsToCombine := completeStaticLibsImplementationJars
1775
1776	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
1777
1778	// Enable dex compilation for the APEX variants, unless it is disabled explicitly
1779	compileDex := Bool(j.dexProperties.Compile_dex) || Bool(j.properties.Installable)
1780
1781	if j.shouldInstrument(ctx) && (!ctx.Device() || compileDex) {
1782		instrumentedOutputFile := j.instrument(ctx, flags, outputFile, jarName, specs)
1783		completeStaticLibsImplementationJarsToCombine = depset.New(depset.PREORDER, android.Paths{instrumentedOutputFile}, nil)
1784		outputFile = instrumentedOutputFile
1785	}
1786
1787	// merge implementation jar with resources if necessary
1788	var implementationAndResourcesJarsToCombine android.Paths
1789	combinedResourceJars := completeStaticLibsResourceJars.ToList()
1790	if len(combinedResourceJars) > 0 {
1791		implementationAndResourcesJarsToCombine = slices.Concat(combinedResourceJars,
1792			completeStaticLibsImplementationJarsToCombine.ToList(), extraDepCombinedJars)
1793	}
1794
1795	if len(implementationAndResourcesJarsToCombine) > 0 {
1796		combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
1797		TransformJarsToJar(ctx, combinedJar, "for resources", implementationAndResourcesJarsToCombine, manifest,
1798			false, nil, nil)
1799		outputFile = combinedJar
1800	}
1801
1802	j.implementationAndResourcesJar = outputFile
1803
1804	if ctx.Device() && compileDex {
1805		if j.hasCode(ctx) {
1806			if j.shouldInstrumentStatic(ctx) {
1807				j.dexer.extraProguardFlagsFiles = append(j.dexer.extraProguardFlagsFiles,
1808					android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags"))
1809			}
1810			// Dex compilation
1811			var dexOutputFile android.Path
1812			params := &compileDexParams{
1813				flags:         flags,
1814				sdkVersion:    j.SdkVersion(ctx),
1815				minSdkVersion: j.MinSdkVersion(ctx),
1816				classesJar:    outputFile,
1817				jarName:       jarName,
1818			}
1819			if j.GetProfileGuided(ctx) && j.optimizeOrObfuscateEnabled(ctx) && !j.EnableProfileRewriting(ctx) {
1820				ctx.PropertyErrorf("enable_profile_rewriting",
1821					"Enable_profile_rewriting must be true when profile_guided dexpreopt and R8 optimization/obfuscation is turned on. The attached profile should be sourced from an unoptimized/unobfuscated APK.",
1822				)
1823			}
1824			if j.EnableProfileRewriting(ctx) {
1825				profile := j.GetProfile(ctx)
1826				if profile == "" || !j.GetProfileGuided(ctx) {
1827					ctx.PropertyErrorf("enable_profile_rewriting", "Profile and Profile_guided must be set when enable_profile_rewriting is true")
1828				}
1829				params.artProfileInput = &profile
1830			}
1831			dexOutputFile, dexArtProfileOutput := j.dexer.compileDex(ctx, params)
1832			if ctx.Failed() {
1833				return nil
1834			}
1835
1836			// If r8/d8 provides a profile that matches the optimized dex, use that for dexpreopt.
1837			if dexArtProfileOutput != nil {
1838				j.dexpreopter.SetRewrittenProfile(dexArtProfileOutput)
1839			}
1840
1841			// merge dex jar with resources if necessary
1842			if len(combinedResourceJars) > 0 {
1843				dexAndResourceJarsToCombine := append(android.Paths{dexOutputFile}, combinedResourceJars...)
1844
1845				combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
1846				TransformJarsToJar(ctx, combinedJar, "for dex resources", dexAndResourceJarsToCombine, android.OptionalPath{},
1847					false, nil, nil)
1848				if *j.dexProperties.Uncompress_dex {
1849					combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName)
1850					TransformZipAlign(ctx, combinedAlignedJar, combinedJar, nil)
1851					dexOutputFile = combinedAlignedJar
1852				} else {
1853					dexOutputFile = combinedJar
1854				}
1855			}
1856
1857			// Initialize the hiddenapi structure.
1858
1859			j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), j.implementationJarFile, j.dexProperties.Uncompress_dex)
1860
1861			// Encode hidden API flags in dex file, if needed.
1862			dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)
1863
1864			j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
1865
1866			// Dexpreopting
1867			libName := android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName())
1868			if j.SdkLibraryName() != nil && strings.HasSuffix(ctx.ModuleName(), ".impl") {
1869				libName = strings.TrimSuffix(libName, ".impl")
1870			}
1871			j.dexpreopt(ctx, libName, dexOutputFile)
1872
1873			outputFile = dexOutputFile
1874
1875			ctx.CheckbuildFile(dexOutputFile)
1876		} else {
1877			// There is no code to compile into a dex jar, make sure the resources are propagated
1878			// to the APK if this is an app.
1879			j.dexJarFile = makeDexJarPathFromPath(combinedResourceJar)
1880		}
1881
1882		if ctx.Failed() {
1883			return nil
1884		}
1885	}
1886
1887	if ctx.Device() {
1888		lintSDKVersion := func(apiLevel android.ApiLevel) android.ApiLevel {
1889			if !apiLevel.IsPreview() {
1890				return apiLevel
1891			} else {
1892				return ctx.Config().DefaultAppTargetSdk(ctx)
1893			}
1894		}
1895
1896		j.linter.name = ctx.ModuleName()
1897		j.linter.srcs = append(srcFiles, nonGeneratedSrcJars...)
1898		j.linter.srcJars, _ = android.FilterPathList(srcJars, nonGeneratedSrcJars)
1899		j.linter.classpath = append(append(android.Paths(nil), flags.bootClasspath...), flags.classpath...)
1900		j.linter.classes = j.implementationJarFile
1901		j.linter.minSdkVersion = lintSDKVersion(j.MinSdkVersion(ctx))
1902		j.linter.targetSdkVersion = lintSDKVersion(j.TargetSdkVersion(ctx))
1903		j.linter.compileSdkVersion = lintSDKVersion(j.SdkVersion(ctx).ApiLevel)
1904		j.linter.compileSdkKind = j.SdkVersion(ctx).Kind
1905		j.linter.javaLanguageLevel = flags.javaVersion.String()
1906		j.linter.kotlinLanguageLevel = "1.3"
1907		j.linter.compile_data = android.PathsForModuleSrc(ctx, j.properties.Compile_data)
1908		if !apexInfo.IsForPlatform() && ctx.Config().UnbundledBuildApps() {
1909			j.linter.buildModuleReportZip = true
1910		}
1911		j.linter.lint(ctx)
1912	}
1913
1914	j.collectTransitiveSrcFiles(ctx, srcFiles)
1915
1916	if len(localImplementationJars) > 0 || len(localResourceJars) > 0 || len(localHeaderJars) > 0 {
1917		ctx.CheckbuildFile(localImplementationJars...)
1918		ctx.CheckbuildFile(localResourceJars...)
1919		ctx.CheckbuildFile(localHeaderJars...)
1920	} else {
1921		// There are no local sources or resources in this module, so there is nothing to checkbuild.
1922		ctx.UncheckedModule()
1923	}
1924
1925	// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
1926	j.outputFile = outputFile.WithoutRel()
1927
1928	return &JavaInfo{
1929		HeaderJars:           android.PathsIfNonNil(j.headerJarFile),
1930		RepackagedHeaderJars: android.PathsIfNonNil(repackagedHeaderJarFile),
1931
1932		LocalHeaderJars:                        localHeaderJars,
1933		TransitiveStaticLibsHeaderJars:         depset.New(depset.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars),
1934		TransitiveStaticLibsImplementationJars: completeStaticLibsImplementationJars,
1935		TransitiveStaticLibsResourceJars:       completeStaticLibsResourceJars,
1936
1937		TransitiveLibsHeaderJarsForR8:       j.transitiveLibsHeaderJarsForR8,
1938		TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
1939		ImplementationAndResourcesJars:      android.PathsIfNonNil(j.implementationAndResourcesJar),
1940		ImplementationJars:                  android.PathsIfNonNil(j.implementationJarFile),
1941		ResourceJars:                        android.PathsIfNonNil(combinedResourceJar),
1942		AidlIncludeDirs:                     j.exportAidlIncludeDirs,
1943		SrcJarArgs:                          j.srcJarArgs,
1944		SrcJarDeps:                          j.srcJarDeps,
1945		TransitiveSrcFiles:                  j.transitiveSrcFiles,
1946		ExportedPlugins:                     j.exportedPluginJars,
1947		ExportedPluginClasses:               j.exportedPluginClasses,
1948		ExportedPluginDisableTurbine:        j.exportedDisableTurbine,
1949		JacocoReportClassesFile:             j.jacocoReportClassesFile,
1950		StubsLinkType:                       j.stubsLinkType,
1951		AconfigIntermediateCacheOutputPaths: j.aconfigCacheFiles,
1952		SdkVersion:                          j.SdkVersion(ctx),
1953		OutputFile:                          j.outputFile,
1954	}
1955}
1956
1957func (j *Module) useCompose(ctx android.BaseModuleContext) bool {
1958	return android.InList("androidx.compose.runtime_runtime", j.staticLibs(ctx))
1959}
1960
1961func collectDepProguardSpecInfo(ctx android.ModuleContext) (transitiveProguardFlags, transitiveUnconditionalExportedFlags []depset.DepSet[android.Path]) {
1962	ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
1963		depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
1964		depTag := ctx.OtherModuleDependencyTag(m)
1965
1966		transitiveUnconditionalExportedFlags = append(transitiveUnconditionalExportedFlags, depProguardInfo.UnconditionallyExportedProguardFlags)
1967		transitiveProguardFlags = append(transitiveProguardFlags, depProguardInfo.UnconditionallyExportedProguardFlags)
1968
1969		if depTag == staticLibTag {
1970			transitiveProguardFlags = append(transitiveProguardFlags, depProguardInfo.ProguardFlagsFiles)
1971		}
1972	})
1973
1974	return transitiveProguardFlags, transitiveUnconditionalExportedFlags
1975}
1976
1977func (j *Module) collectProguardSpecInfo(ctx android.ModuleContext) ProguardSpecInfo {
1978	transitiveProguardFlags, transitiveUnconditionalExportedFlags := collectDepProguardSpecInfo(ctx)
1979
1980	directUnconditionalExportedFlags := android.Paths{}
1981	proguardFlagsForThisModule := android.PathsForModuleSrc(ctx, j.dexProperties.Optimize.Proguard_flags_files)
1982	exportUnconditionally := proptools.Bool(j.dexProperties.Optimize.Export_proguard_flags_files)
1983	if exportUnconditionally {
1984		// if we explicitly export, then our unconditional exports are the same as our transitive flags
1985		transitiveUnconditionalExportedFlags = transitiveProguardFlags
1986		directUnconditionalExportedFlags = proguardFlagsForThisModule
1987	}
1988
1989	return ProguardSpecInfo{
1990		Export_proguard_flags_files: exportUnconditionally,
1991		ProguardFlagsFiles: depset.New[android.Path](
1992			depset.POSTORDER,
1993			proguardFlagsForThisModule,
1994			transitiveProguardFlags,
1995		),
1996		UnconditionallyExportedProguardFlags: depset.New[android.Path](
1997			depset.POSTORDER,
1998			directUnconditionalExportedFlags,
1999			transitiveUnconditionalExportedFlags,
2000		),
2001	}
2002
2003}
2004
2005// Returns a copy of the supplied flags, but with all the errorprone-related
2006// fields copied to the regular build's fields.
2007func enableErrorproneFlags(flags javaBuilderFlags) javaBuilderFlags {
2008	flags.processorPath = append(flags.errorProneProcessorPath, flags.processorPath...)
2009
2010	if len(flags.errorProneExtraJavacFlags) > 0 {
2011		if len(flags.javacFlags) > 0 {
2012			flags.javacFlags += " " + flags.errorProneExtraJavacFlags
2013		} else {
2014			flags.javacFlags = flags.errorProneExtraJavacFlags
2015		}
2016	}
2017	return flags
2018}
2019
2020func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, idx int,
2021	srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.Path {
2022
2023	kzipName := pathtools.ReplaceExtension(jarName, "kzip")
2024	annoSrcJar := android.PathForModuleOut(ctx, "javac", "anno.srcjar")
2025	if idx >= 0 {
2026		kzipName = strings.TrimSuffix(jarName, filepath.Ext(jarName)) + strconv.Itoa(idx) + ".kzip"
2027		annoSrcJar = android.PathForModuleOut(ctx, "javac", "anno-"+strconv.Itoa(idx)+".srcjar")
2028		jarName += strconv.Itoa(idx)
2029	}
2030
2031	classes := android.PathForModuleOut(ctx, "javac", jarName)
2032	TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, annoSrcJar, flags, extraJarDeps)
2033
2034	if ctx.Config().EmitXrefRules() && ctx.Module() == ctx.PrimaryModule() {
2035		extractionFile := android.PathForModuleOut(ctx, kzipName)
2036		emitXrefRule(ctx, extractionFile, idx, srcFiles, srcJars, flags, extraJarDeps)
2037		j.kytheFiles = append(j.kytheFiles, extractionFile)
2038	}
2039
2040	if len(flags.processorPath) > 0 {
2041		j.annoSrcJars = append(j.annoSrcJars, annoSrcJar)
2042	}
2043
2044	return classes
2045}
2046
2047// Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user,
2048// since some of these flags may be used internally.
2049func CheckKotlincFlags(ctx android.ModuleContext, flags []string) {
2050	for _, flag := range flags {
2051		flag = strings.TrimSpace(flag)
2052
2053		if !strings.HasPrefix(flag, "-") {
2054			ctx.PropertyErrorf("kotlincflags", "Flag `%s` must start with `-`", flag)
2055		} else if strings.HasPrefix(flag, "-Xintellij-plugin-root") {
2056			ctx.PropertyErrorf("kotlincflags",
2057				"Bad flag: `%s`, only use internal compiler for consistency.", flag)
2058		} else if slices.ContainsFunc(config.KotlincIllegalFlags, func(f string) bool {
2059			return strings.HasPrefix(flag, f)
2060		}) {
2061			ctx.PropertyErrorf("kotlincflags", "Flag `%s` already used by build system", flag)
2062		} else if flag == "-include-runtime" {
2063			ctx.PropertyErrorf("kotlincflags", "Bad flag: `%s`, do not include runtime.", flag)
2064		} else {
2065			args := strings.Split(flag, " ")
2066			if args[0] == "-kotlin-home" {
2067				ctx.PropertyErrorf("kotlincflags",
2068					"Bad flag: `%s`, kotlin home already set to default (path to kotlinc in the repo).", flag)
2069			}
2070		}
2071	}
2072}
2073
2074func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
2075	deps deps, flags javaBuilderFlags, jarName string,
2076	extraJars android.Paths) (localHeaderJars android.Paths, combinedHeaderJar android.Path) {
2077
2078	if len(srcFiles) > 0 || len(srcJars) > 0 {
2079		// Compile java sources into turbine.jar.
2080		turbineJar := android.PathForModuleOut(ctx, "turbine", jarName)
2081		TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags)
2082		localHeaderJars = append(localHeaderJars, turbineJar)
2083	}
2084
2085	localHeaderJars = append(localHeaderJars, extraJars...)
2086
2087	// Combine any static header libraries into classes-header.jar. If there is only
2088	// one input jar this step will be skipped.
2089	depSet := depset.New(depset.PREORDER, localHeaderJars, deps.transitiveStaticLibsHeaderJars)
2090	jars := depSet.ToList()
2091
2092	// we cannot skip the combine step for now if there is only one jar
2093	// since we have to strip META-INF/TRANSITIVE dir from turbine.jar
2094	combinedHeaderJarOutputPath := android.PathForModuleOut(ctx, "turbine-combined", jarName)
2095	TransformJarsToJar(ctx, combinedHeaderJarOutputPath, "for turbine", jars, android.OptionalPath{},
2096		false, nil, []string{"META-INF/TRANSITIVE"})
2097
2098	return localHeaderJars, combinedHeaderJarOutputPath
2099}
2100
2101func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
2102	classesJar android.Path, jarName string, specs string) android.Path {
2103
2104	jacocoReportClassesFile := android.PathForModuleOut(ctx, "jacoco-report-classes", jarName)
2105	instrumentedJar := android.PathForModuleOut(ctx, "jacoco", jarName)
2106
2107	jacocoInstrumentJar(ctx, instrumentedJar, jacocoReportClassesFile, classesJar, specs)
2108
2109	j.jacocoReportClassesFile = jacocoReportClassesFile
2110
2111	return instrumentedJar
2112}
2113
2114type providesTransitiveHeaderJarsForR8 struct {
2115	// set of header jars for all transitive libs deps
2116	transitiveLibsHeaderJarsForR8 depset.DepSet[android.Path]
2117	// set of header jars for all transitive static libs deps
2118	transitiveStaticLibsHeaderJarsForR8 depset.DepSet[android.Path]
2119}
2120
2121// collectTransitiveHeaderJarsForR8 visits direct dependencies and collects all transitive libs and static_libs
2122// header jars.  The semantics of the collected jars are odd (it collects combined jars that contain the static
2123// libs, but also the static libs, and it collects transitive libs dependencies of static_libs), so these
2124// are only used to expand the --lib arguments to R8.
2125func (j *providesTransitiveHeaderJarsForR8) collectTransitiveHeaderJarsForR8(ctx android.ModuleContext) {
2126	directLibs := android.Paths{}
2127	directStaticLibs := android.Paths{}
2128	transitiveLibs := []depset.DepSet[android.Path]{}
2129	transitiveStaticLibs := []depset.DepSet[android.Path]{}
2130	ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
2131		// don't add deps of the prebuilt version of the same library
2132		if ctx.ModuleName() == android.RemoveOptionalPrebuiltPrefix(module.Name()) {
2133			return
2134		}
2135
2136		if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
2137			tag := ctx.OtherModuleDependencyTag(module)
2138			_, isUsesLibDep := tag.(usesLibraryDependencyTag)
2139			if tag == libTag || tag == r8LibraryJarTag || isUsesLibDep {
2140				directLibs = append(directLibs, dep.HeaderJars...)
2141			} else if tag == staticLibTag {
2142				directStaticLibs = append(directStaticLibs, dep.HeaderJars...)
2143			} else {
2144				// Don't propagate transitive libs for other kinds of dependencies.
2145				return
2146			}
2147
2148			transitiveLibs = append(transitiveLibs, dep.TransitiveLibsHeaderJarsForR8)
2149			transitiveStaticLibs = append(transitiveStaticLibs, dep.TransitiveStaticLibsHeaderJarsForR8)
2150		}
2151	})
2152	j.transitiveLibsHeaderJarsForR8 = depset.New(depset.POSTORDER, directLibs, transitiveLibs)
2153	j.transitiveStaticLibsHeaderJarsForR8 = depset.New(depset.POSTORDER, directStaticLibs, transitiveStaticLibs)
2154}
2155
2156func (j *Module) HeaderJars() android.Paths {
2157	if j.headerJarFile == nil {
2158		return nil
2159	}
2160	return android.Paths{j.headerJarFile}
2161}
2162
2163func (j *Module) ImplementationJars() android.Paths {
2164	if j.implementationJarFile == nil {
2165		return nil
2166	}
2167	return android.Paths{j.implementationJarFile}
2168}
2169
2170func (j *Module) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
2171	return j.dexJarFile
2172}
2173
2174func (j *Module) DexJarInstallPath() android.Path {
2175	return j.installFile
2176}
2177
2178func (j *Module) ImplementationAndResourcesJars() android.Paths {
2179	if j.implementationAndResourcesJar == nil {
2180		return nil
2181	}
2182	return android.Paths{j.implementationAndResourcesJar}
2183}
2184
2185func (j *Module) AidlIncludeDirs() android.Paths {
2186	// exportAidlIncludeDirs is type android.Paths already
2187	return j.exportAidlIncludeDirs
2188}
2189
2190func (j *Module) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
2191	return j.classLoaderContexts
2192}
2193
2194// Collect information for opening IDE project files in java/jdeps.go.
2195func (j *Module) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
2196	if j.expandJarjarRules != nil {
2197		dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
2198	}
2199	if j.headerJarFile != nil {
2200		// Add the header jar so that the rdeps can be resolved to the repackaged classes.
2201		dpInfo.Jars = append(dpInfo.Jars, j.headerJarFile.String())
2202	}
2203	dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...)
2204	dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...)
2205	dpInfo.SrcJars = append(dpInfo.SrcJars, j.annoSrcJars.Strings()...)
2206	dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...)
2207	dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...)
2208	dpInfo.Static_libs = append(dpInfo.Static_libs, j.staticLibs(ctx)...)
2209	dpInfo.Libs = append(dpInfo.Libs, j.properties.Libs...)
2210}
2211
2212func (j *Module) CompilerDeps() []string {
2213	return j.compileDepNames
2214}
2215
2216func (j *Module) hasCode(ctx android.ModuleContext) bool {
2217	srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
2218	return len(srcFiles) > 0 || len(ctx.GetDirectDepsProxyWithTag(staticLibTag)) > 0
2219}
2220
2221// Implements android.ApexModule
2222func (m *Module) GetDepInSameApexChecker() android.DepInSameApexChecker {
2223	return JavaDepInSameApexChecker{}
2224}
2225
2226type JavaDepInSameApexChecker struct {
2227	android.BaseDepInSameApexChecker
2228}
2229
2230func (m JavaDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool {
2231	return depIsInSameApex(tag)
2232}
2233
2234// Implements android.ApexModule
2235func (j *Module) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
2236	sdkVersionSpec := j.SdkVersion(ctx)
2237	minSdkVersion := j.MinSdkVersion(ctx)
2238
2239	// If the module is compiling against core (via sdk_version), skip comparison check.
2240	if sdkVersionSpec.Kind == android.SdkCore {
2241		return android.MinApiLevel
2242	}
2243
2244	return minSdkVersion
2245}
2246
2247func (j *Module) Stem() string {
2248	if j.stem == "" {
2249		panic("Stem() called before stem property was set")
2250	}
2251	return j.stem
2252}
2253
2254func (j *Module) JacocoReportClassesFile() android.Path {
2255	return j.jacocoReportClassesFile
2256}
2257
2258func (j *Module) collectTransitiveSrcFiles(ctx android.ModuleContext, mine android.Paths) {
2259	var fromDeps []depset.DepSet[android.Path]
2260	ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
2261		tag := ctx.OtherModuleDependencyTag(module)
2262		if tag == staticLibTag {
2263			if depInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
2264				fromDeps = append(fromDeps, depInfo.TransitiveSrcFiles)
2265			}
2266		}
2267	})
2268
2269	j.transitiveSrcFiles = depset.New(depset.POSTORDER, mine, fromDeps)
2270}
2271
2272func (j *Module) IsInstallable() bool {
2273	return Bool(j.properties.Installable)
2274}
2275
2276type sdkLinkType int
2277
2278const (
2279	// TODO(jiyong) rename these for better readability. Make the allowed
2280	// and disallowed link types explicit
2281	// order is important here. See rank()
2282	javaCore sdkLinkType = iota
2283	javaSdk
2284	javaSystem
2285	javaModule
2286	javaSystemServer
2287	javaPlatform
2288)
2289
2290func (lt sdkLinkType) String() string {
2291	switch lt {
2292	case javaCore:
2293		return "core Java API"
2294	case javaSdk:
2295		return "Android API"
2296	case javaSystem:
2297		return "system API"
2298	case javaModule:
2299		return "module API"
2300	case javaSystemServer:
2301		return "system server API"
2302	case javaPlatform:
2303		return "private API"
2304	default:
2305		panic(fmt.Errorf("unrecognized linktype: %d", lt))
2306	}
2307}
2308
2309// rank determines the total order among sdkLinkType. An SDK link type of rank A can link to
2310// another SDK link type of rank B only when B <= A. For example, a module linking to Android SDK
2311// can't statically depend on modules that use Platform API.
2312func (lt sdkLinkType) rank() int {
2313	return int(lt)
2314}
2315
2316type moduleWithSdkDep interface {
2317	android.Module
2318	getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool)
2319}
2320
2321func sdkLinkTypeFromSdkKind(k android.SdkKind) sdkLinkType {
2322	switch k {
2323	case android.SdkCore:
2324		return javaCore
2325	case android.SdkSystem:
2326		return javaSystem
2327	case android.SdkPublic:
2328		return javaSdk
2329	case android.SdkModule:
2330		return javaModule
2331	case android.SdkSystemServer:
2332		return javaSystemServer
2333	case android.SdkPrivate, android.SdkNone, android.SdkCorePlatform, android.SdkTest:
2334		return javaPlatform
2335	default:
2336		return javaSdk
2337	}
2338}
2339
2340func (m *Module) getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool) {
2341	switch name {
2342	case android.SdkCore.DefaultJavaLibraryName(),
2343		"legacy.core.platform.api.stubs",
2344		"stable.core.platform.api.stubs",
2345		"stub-annotations", "private-stub-annotations-jar",
2346		"core-lambda-stubs",
2347		"core-generated-annotation-stubs",
2348		// jacocoagent only uses core APIs, but has to specify a non-core sdk_version so it can use
2349		// a prebuilt SDK to avoid circular dependencies when it statically included in the bootclasspath.
2350		"jacocoagent":
2351		return javaCore, true
2352	case android.SdkPublic.DefaultJavaLibraryName():
2353		return javaSdk, true
2354	case android.SdkSystem.DefaultJavaLibraryName():
2355		return javaSystem, true
2356	case android.SdkModule.DefaultJavaLibraryName():
2357		return javaModule, true
2358	case android.SdkSystemServer.DefaultJavaLibraryName():
2359		return javaSystemServer, true
2360	case android.SdkTest.DefaultJavaLibraryName():
2361		return javaSystem, true
2362	}
2363
2364	if stub, linkType := moduleStubLinkType(m); stub {
2365		return linkType, true
2366	}
2367
2368	ver := m.SdkVersion(ctx)
2369	if !ver.Valid() {
2370		panic(fmt.Errorf("sdk_version is invalid. got %q", ver.Raw))
2371	}
2372
2373	return sdkLinkTypeFromSdkKind(ver.Kind), false
2374}
2375
2376// checkSdkLinkType make sures the given dependency doesn't have a lower SDK link type rank than
2377// this module's. See the comment on rank() for details and an example.
2378func (j *Module) checkSdkLinkType(
2379	ctx android.ModuleContext, dep android.ModuleProxy) {
2380	if ctx.Host() {
2381		return
2382	}
2383
2384	myLinkType, stubs := j.getSdkLinkType(ctx, ctx.ModuleName())
2385	if stubs {
2386		return
2387	}
2388	info, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider)
2389	if !ok || info.ModuleWithSdkDepInfo == nil {
2390		panic(fmt.Errorf("dependency doesn't have ModuleWithSdkDepInfo: %v", dep))
2391	}
2392
2393	depLinkType := info.ModuleWithSdkDepInfo.SdkLinkType
2394
2395	if myLinkType.rank() < depLinkType.rank() {
2396		ctx.ModuleErrorf("compiles against %v, but dependency %q is compiling against %v. "+
2397			"In order to fix this, consider adjusting sdk_version: OR platform_apis: "+
2398			"property of the source or target module so that target module is built "+
2399			"with the same or smaller API set when compared to the source.",
2400			myLinkType, ctx.OtherModuleName(dep), depLinkType)
2401	}
2402}
2403
2404func (j *Module) collectDeps(ctx android.ModuleContext) deps {
2405	var deps deps
2406
2407	sdkLinkType, _ := j.getSdkLinkType(ctx, ctx.ModuleName())
2408
2409	j.collectTransitiveHeaderJarsForR8(ctx)
2410
2411	var transitiveBootClasspathHeaderJars []depset.DepSet[android.Path]
2412	var transitiveClasspathHeaderJars []depset.DepSet[android.Path]
2413	var transitiveJava9ClasspathHeaderJars []depset.DepSet[android.Path]
2414	var transitiveStaticJarsHeaderLibs []depset.DepSet[android.Path]
2415	var transitiveStaticJarsImplementationLibs []depset.DepSet[android.Path]
2416	var transitiveStaticJarsResourceLibs []depset.DepSet[android.Path]
2417
2418	ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
2419		otherName := ctx.OtherModuleName(module)
2420		tag := ctx.OtherModuleDependencyTag(module)
2421
2422		if IsJniDepTag(tag) {
2423			// Handled by AndroidApp.collectAppDeps
2424			return
2425		}
2426		if tag == certificateTag {
2427			// Handled by AndroidApp.collectAppDeps
2428			return
2429		}
2430
2431		if sdkInfo, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
2432			switch tag {
2433			case sdkLibTag, libTag, staticLibTag:
2434				generatingLibsString := android.PrettyConcat(
2435					getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or")
2436				ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString)
2437			}
2438		} else if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
2439			if sdkLinkType != javaPlatform {
2440				if syspropDep, ok := android.OtherModuleProvider(ctx, module, SyspropPublicStubInfoProvider); ok {
2441					// dep is a sysprop implementation library, but this module is not linking against
2442					// the platform, so it gets the sysprop public stubs library instead.  Replace
2443					// dep with the JavaInfo from the SyspropPublicStubInfoProvider.
2444					dep = syspropDep.JavaInfo
2445				}
2446			}
2447			switch tag {
2448			case bootClasspathTag:
2449				deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...)
2450				transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
2451			case sdkLibTag, libTag, instrumentationForTag:
2452				if _, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
2453					ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a libs dependency", otherName)
2454				}
2455				deps.classpath = append(deps.classpath, dep.HeaderJars...)
2456				deps.dexClasspath = append(deps.dexClasspath, dep.HeaderJars...)
2457				if len(dep.RepackagedHeaderJars) == 1 && !slices.Contains(dep.HeaderJars, dep.RepackagedHeaderJars[0]) {
2458					deps.classpath = append(deps.classpath, dep.RepackagedHeaderJars...)
2459					deps.dexClasspath = append(deps.dexClasspath, dep.RepackagedHeaderJars...)
2460				}
2461				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
2462				addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
2463				deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
2464
2465				transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
2466			case java9LibTag:
2467				deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
2468				transitiveJava9ClasspathHeaderJars = append(transitiveJava9ClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
2469			case staticLibTag:
2470				if _, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
2471					ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a static_libs dependency", otherName)
2472				}
2473				deps.classpath = append(deps.classpath, dep.HeaderJars...)
2474				deps.staticJars = append(deps.staticJars, dep.ImplementationJars...)
2475				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars...)
2476				deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars...)
2477				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
2478				addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
2479				// Turbine doesn't run annotation processors, so any module that uses an
2480				// annotation processor that generates API is incompatible with the turbine
2481				// optimization.
2482				deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
2483				deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
2484
2485				transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
2486				transitiveStaticJarsHeaderLibs = append(transitiveStaticJarsHeaderLibs, dep.TransitiveStaticLibsHeaderJars)
2487				transitiveStaticJarsImplementationLibs = append(transitiveStaticJarsImplementationLibs, dep.TransitiveStaticLibsImplementationJars)
2488				transitiveStaticJarsResourceLibs = append(transitiveStaticJarsResourceLibs, dep.TransitiveStaticLibsResourceJars)
2489			case pluginTag:
2490				if plugin, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
2491					if plugin.ProcessorClass != nil {
2492						addPlugins(&deps, dep.ImplementationAndResourcesJars, *plugin.ProcessorClass)
2493					} else {
2494						addPlugins(&deps, dep.ImplementationAndResourcesJars)
2495					}
2496					// Turbine doesn't run annotation processors, so any module that uses an
2497					// annotation processor that generates API is incompatible with the turbine
2498					// optimization.
2499					deps.disableTurbine = deps.disableTurbine || plugin.GeneratesApi
2500				} else {
2501					ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
2502				}
2503			case errorpronePluginTag:
2504				if _, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
2505					deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, dep.ImplementationAndResourcesJars...)
2506				} else {
2507					ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
2508				}
2509			case exportedPluginTag:
2510				if plugin, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok {
2511					j.exportedPluginJars = append(j.exportedPluginJars, dep.ImplementationAndResourcesJars...)
2512					if plugin.ProcessorClass != nil {
2513						j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.ProcessorClass)
2514					}
2515					// Turbine doesn't run annotation processors, so any module that uses an
2516					// annotation processor that generates API is incompatible with the turbine
2517					// optimization.
2518					j.exportedDisableTurbine = plugin.GeneratesApi
2519				} else {
2520					ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName)
2521				}
2522			case kotlinPluginTag:
2523				if _, ok := android.OtherModuleProvider(ctx, module, KotlinPluginInfoProvider); ok {
2524					deps.kotlinPlugins = append(deps.kotlinPlugins, dep.ImplementationAndResourcesJars...)
2525				} else {
2526					ctx.PropertyErrorf("kotlin_plugins", "%q is not a kotlin_plugin module", otherName)
2527				}
2528			case syspropPublicStubDepTag:
2529				// This is a sysprop implementation library, forward the JavaInfoProvider from
2530				// the corresponding sysprop public stub library as SyspropPublicStubInfoProvider.
2531				android.SetProvider(ctx, SyspropPublicStubInfoProvider, SyspropPublicStubInfo{
2532					JavaInfo: dep,
2533				})
2534			}
2535		} else if dep, ok := android.OtherModuleProvider(ctx, module, android.SourceFilesInfoProvider); ok {
2536			switch tag {
2537			case sdkLibTag, libTag:
2538				checkProducesJars(ctx, dep, module)
2539				deps.classpath = append(deps.classpath, dep.Srcs...)
2540				deps.dexClasspath = append(deps.classpath, dep.Srcs...)
2541				transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars,
2542					depset.New(depset.PREORDER, dep.Srcs, nil))
2543			case staticLibTag:
2544				checkProducesJars(ctx, dep, module)
2545				deps.classpath = append(deps.classpath, dep.Srcs...)
2546				deps.staticJars = append(deps.staticJars, dep.Srcs...)
2547				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs...)
2548
2549				depHeaderJars := depset.New(depset.PREORDER, dep.Srcs, nil)
2550				transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, depHeaderJars)
2551				transitiveStaticJarsHeaderLibs = append(transitiveStaticJarsHeaderLibs, depHeaderJars)
2552				transitiveStaticJarsImplementationLibs = append(transitiveStaticJarsImplementationLibs, depHeaderJars)
2553			}
2554		} else if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok {
2555			switch tag {
2556			case staticLibTag:
2557				deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
2558			}
2559		} else {
2560			switch tag {
2561			case bootClasspathTag:
2562				// If a system modules dependency has been added to the bootclasspath
2563				// then add its libs to the bootclasspath.
2564				if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok {
2565					deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars...)
2566					transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars,
2567						sm.TransitiveStaticLibsHeaderJars)
2568				} else {
2569					ctx.PropertyErrorf("boot classpath dependency %q does not provide SystemModulesProvider",
2570						ctx.OtherModuleName(module))
2571				}
2572
2573			case systemModulesTag:
2574				if deps.systemModules != nil {
2575					panic("Found two system module dependencies")
2576				}
2577				if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok {
2578					deps.systemModules = &systemModules{sm.OutputDir, sm.OutputDirDeps}
2579				} else {
2580					ctx.PropertyErrorf("system modules dependency %q does not provide SystemModulesProvider",
2581						ctx.OtherModuleName(module))
2582				}
2583
2584			case instrumentationForTag:
2585				ctx.PropertyErrorf("instrumentation_for", "dependency %q of type %q does not provide JavaInfo so is unsuitable for use with this property", ctx.OtherModuleName(module), ctx.OtherModuleType(module))
2586			}
2587		}
2588
2589		if android.InList(tag, compileDependencyTags) {
2590			// Add the dependency name to compileDepNames so that it can be recorded in module_bp_java_deps.json
2591			j.compileDepNames = append(j.compileDepNames, otherName)
2592		}
2593
2594		addCLCFromDep(ctx, module, j.classLoaderContexts)
2595		addMissingOptionalUsesLibsFromDep(ctx, module, &j.usesLibrary)
2596	})
2597
2598	deps.transitiveStaticLibsHeaderJars = transitiveStaticJarsHeaderLibs
2599	deps.transitiveStaticLibsImplementationJars = transitiveStaticJarsImplementationLibs
2600	deps.transitiveStaticLibsResourceJars = transitiveStaticJarsResourceLibs
2601
2602	depSet := depset.New(depset.PREORDER, nil, transitiveClasspathHeaderJars)
2603	deps.classpath = depSet.ToList()
2604	depSet = depset.New(depset.PREORDER, nil, transitiveBootClasspathHeaderJars)
2605	deps.bootClasspath = depSet.ToList()
2606	depSet = depset.New(depset.PREORDER, nil, transitiveJava9ClasspathHeaderJars)
2607	deps.java9Classpath = depSet.ToList()
2608
2609	if ctx.Device() {
2610		sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
2611		if sdkDep.invalidVersion {
2612			ctx.AddMissingDependencies(sdkDep.bootclasspath)
2613			ctx.AddMissingDependencies(sdkDep.java9Classpath)
2614		} else if sdkDep.useFiles {
2615			// sdkDep.jar is actually equivalent to turbine header.jar.
2616			deps.classpath = append(slices.Clone(classpath(sdkDep.jars)), deps.classpath...)
2617			deps.dexClasspath = append(slices.Clone(classpath(sdkDep.jars)), deps.dexClasspath...)
2618			deps.aidlPreprocess = sdkDep.aidl
2619			// Add the sdk module dependency to `compileDepNames`.
2620			// This ensures that the dependency is reported in `module_bp_java_deps.json`
2621			// TODO (b/358608607): Move this to decodeSdkDep
2622			sdkSpec := android.SdkContext(j).SdkVersion(ctx)
2623			j.compileDepNames = append(j.compileDepNames, fmt.Sprintf("sdk_%s_%s_android", sdkSpec.Kind.String(), sdkSpec.ApiLevel.String()))
2624		} else {
2625			deps.aidlPreprocess = sdkDep.aidl
2626		}
2627	}
2628
2629	return deps
2630}
2631
2632// Provider for jarjar renaming rules.
2633//
2634// Modules can set their jarjar renaming rules with addJarJarRenameRule, and those renamings will be
2635// passed to all rdeps.  The typical way that these renamings will NOT be inherited is when a module
2636// links against stubs -- these are not passed through stubs. The classes will remain unrenamed on
2637// classes until a module with jarjar_prefix is reached, and all as yet unrenamed classes will then
2638// be renamed from that module.
2639// TODO: Add another property to suppress the forwarding of
2640type DependencyUse int
2641
2642const (
2643	RenameUseInvalid DependencyUse = iota
2644	RenameUseInclude
2645	RenameUseExclude
2646)
2647
2648type JarJarProviderData struct {
2649	// Mapping of class names: original --> renamed.  If the value is "", the class will be
2650	// renamed by the next rdep that has the jarjar_prefix attribute (or this module if it has
2651	// attribute). Rdeps of that module will inherit the renaming.
2652	Rename map[string]string
2653}
2654
2655func (this JarJarProviderData) GetDebugString() string {
2656	result := ""
2657	for _, k := range android.SortedKeys(this.Rename) {
2658		v := this.Rename[k]
2659		if strings.Contains(k, "android.companion.virtual.flags.FakeFeatureFlagsImpl") {
2660			result += k + "--&gt;" + v + ";"
2661		}
2662	}
2663	return result
2664}
2665
2666var JarJarProvider = blueprint.NewProvider[JarJarProviderData]()
2667
2668var overridableJarJarPrefix = "com.android.internal.hidden_from_bootclasspath"
2669
2670func init() {
2671	android.SetJarJarPrefixHandler(mergeJarJarPrefixes)
2672
2673	gob.Register(BaseJarJarProviderData{})
2674}
2675
2676// BaseJarJarProviderData contains information that will propagate across dependencies regardless of
2677// whether they are java modules or not.
2678type BaseJarJarProviderData struct {
2679	JarJarProviderData JarJarProviderData
2680}
2681
2682func (this BaseJarJarProviderData) GetDebugString() string {
2683	return this.JarJarProviderData.GetDebugString()
2684}
2685
2686var BaseJarJarProvider = blueprint.NewProvider[BaseJarJarProviderData]()
2687
2688// mergeJarJarPrefixes is called immediately before module.GenerateAndroidBuildActions is called.
2689// Since there won't be a JarJarProvider, we create the BaseJarJarProvider if any of our deps have
2690// either JarJarProvider or BaseJarJarProvider.
2691func mergeJarJarPrefixes(ctx android.ModuleContext) {
2692	mod := ctx.Module()
2693	// Explicitly avoid propagating into some module types.
2694	switch reflect.TypeOf(mod).String() {
2695	case "*java.Droidstubs":
2696		return
2697	}
2698	jarJarData := collectDirectDepsProviders(ctx)
2699	if jarJarData != nil {
2700		providerData := BaseJarJarProviderData{
2701			JarJarProviderData: *jarJarData,
2702		}
2703		android.SetProvider(ctx, BaseJarJarProvider, providerData)
2704	}
2705
2706}
2707
2708// Add a jarjar renaming rule to this module, to be inherited to all dependent modules.
2709func (module *Module) addJarJarRenameRule(original string, renamed string) {
2710	if module.jarjarRenameRules == nil {
2711		module.jarjarRenameRules = make(map[string]string)
2712	}
2713	module.jarjarRenameRules[original] = renamed
2714}
2715
2716func collectDirectDepsProviders(ctx android.ModuleContext) (result *JarJarProviderData) {
2717	// Gather repackage information from deps
2718	// If the dep jas a JarJarProvider, it is used.  Otherwise, any BaseJarJarProvider is used.
2719
2720	module := ctx.Module()
2721	moduleName := module.Name()
2722
2723	ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
2724		tag := ctx.OtherModuleDependencyTag(m)
2725		// This logic mirrors that in (*Module).collectDeps above.  There are several places
2726		// where we explicitly return RenameUseExclude, even though it is the default, to
2727		// indicate that it has been verified to be the case.
2728		//
2729		// Note well: there are probably cases that are getting to the unconditional return
2730		// and are therefore wrong.
2731		shouldIncludeRenames := func() DependencyUse {
2732			if moduleName == m.Name() {
2733				return RenameUseInclude // If we have the same module name, include the renames.
2734			}
2735			if sc, ok := module.(android.SdkContext); ok {
2736				if ctx.Device() {
2737					sdkDep := decodeSdkDep(ctx, sc)
2738					if !sdkDep.invalidVersion && sdkDep.useFiles {
2739						return RenameUseExclude
2740					}
2741				}
2742			}
2743			if IsJniDepTag(tag) || tag == certificateTag || tag == proguardRaiseTag {
2744				return RenameUseExclude
2745			}
2746			if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
2747				switch tag {
2748				case sdkLibTag, libTag:
2749					return RenameUseExclude // matches collectDeps()
2750				}
2751				return RenameUseInvalid // dep is not used in collectDeps()
2752			} else if ji, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
2753				switch ji.StubsLinkType {
2754				case Stubs:
2755					return RenameUseExclude
2756				case Implementation:
2757					return RenameUseInclude
2758				default:
2759					//fmt.Printf("collectDirectDepsProviders: %v -> %v StubsLinkType unknown\n", module, m)
2760					// Fall through to the heuristic logic.
2761				}
2762				if _, ok := android.OtherModuleProvider(ctx, m, android.CodegenInfoProvider); ok {
2763					// Probably a java_aconfig_library module.
2764					return RenameUseInclude
2765				}
2766				switch tag {
2767				case bootClasspathTag:
2768					return RenameUseExclude
2769				case sdkLibTag, libTag, instrumentationForTag:
2770					return RenameUseInclude
2771				case java9LibTag:
2772					return RenameUseExclude
2773				case staticLibTag:
2774					return RenameUseInclude
2775				case pluginTag:
2776					return RenameUseInclude
2777				case errorpronePluginTag:
2778					return RenameUseInclude
2779				case exportedPluginTag:
2780					return RenameUseInclude
2781				case kotlinPluginTag:
2782					return RenameUseInclude
2783				default:
2784					return RenameUseExclude
2785				}
2786			} else if _, ok := android.OtherModuleProvider(ctx, m, android.SourceFilesInfoProvider); ok {
2787				switch tag {
2788				case sdkLibTag, libTag, staticLibTag:
2789					return RenameUseInclude
2790				default:
2791					return RenameUseExclude
2792				}
2793			} else if _, ok := android.OtherModuleProvider(ctx, m, android.CodegenInfoProvider); ok {
2794				return RenameUseInclude
2795			} else {
2796				switch tag {
2797				case bootClasspathTag:
2798					return RenameUseExclude
2799				case systemModulesTag:
2800					return RenameUseInclude
2801				}
2802			}
2803			// If we got here, choose the safer option, which may lead to a build failure, rather
2804			// than runtime failures on the device.
2805			return RenameUseExclude
2806		}
2807
2808		if result == nil {
2809			result = &JarJarProviderData{
2810				Rename: make(map[string]string),
2811			}
2812		}
2813		how := shouldIncludeRenames()
2814		if how != RenameUseInclude {
2815			// Nothing to merge.
2816			return
2817		}
2818
2819		merge := func(theirs *JarJarProviderData) {
2820			for orig, renamed := range theirs.Rename {
2821				if preexisting, exists := (*result).Rename[orig]; !exists || preexisting == "" {
2822					result.Rename[orig] = renamed
2823				} else if preexisting != "" && renamed != "" && preexisting != renamed {
2824					if strings.HasPrefix(preexisting, overridableJarJarPrefix) {
2825						result.Rename[orig] = renamed
2826					} else if !strings.HasPrefix(renamed, overridableJarJarPrefix) {
2827						ctx.ModuleErrorf("1. Conflicting jarjar rules inherited for class: %s (%s and %s)", orig, renamed, preexisting, ctx.ModuleName(), m.Name())
2828						continue
2829					}
2830				}
2831			}
2832		}
2833		if theirs, ok := android.OtherModuleProvider(ctx, m, JarJarProvider); ok {
2834			merge(&theirs)
2835		} else if theirs, ok := android.OtherModuleProvider(ctx, m, BaseJarJarProvider); ok {
2836			// TODO: if every java.Module should have a JarJarProvider, and we find only the
2837			// BaseJarJarProvider, then there is a bug.  Consider seeing if m can be cast
2838			// to java.Module.
2839			merge(&theirs.JarJarProviderData)
2840		}
2841	})
2842	return
2843}
2844
2845func (this Module) GetDebugString() string {
2846	return "sdk_version=" + proptools.String(this.deviceProperties.Sdk_version)
2847}
2848
2849// Merge the jarjar rules we inherit from our dependencies, any that have been added directly to
2850// us, and if it's been set, apply the jarjar_prefix property to rename them.
2851func (module *Module) collectJarJarRules(ctx android.ModuleContext) *JarJarProviderData {
2852	// Gather repackage information from deps
2853	result := collectDirectDepsProviders(ctx)
2854
2855	add := func(orig string, renamed string) {
2856		if result == nil {
2857			result = &JarJarProviderData{
2858				Rename: make(map[string]string),
2859			}
2860		}
2861		if renamed != "" {
2862			if preexisting, exists := (*result).Rename[orig]; exists && preexisting != renamed {
2863				ctx.ModuleErrorf("Conflicting jarjar rules inherited for class: %s (%s and %s)", orig, renamed, preexisting)
2864				return
2865			}
2866		}
2867		(*result).Rename[orig] = renamed
2868	}
2869
2870	// Update that with entries we've stored for ourself
2871	for orig, renamed := range module.jarjarRenameRules {
2872		add(orig, renamed)
2873	}
2874
2875	// Update that with entries given in the jarjar_rename property.
2876	for _, orig := range module.properties.Jarjar_rename {
2877		add(orig, "")
2878	}
2879
2880	// If there are no renamings, then jarjar_prefix does nothing, so skip the extra work.
2881	if result == nil {
2882		return nil
2883	}
2884
2885	// If they've given us a jarjar_prefix property, then we will use that to rename any classes
2886	// that have not yet been renamed.
2887	prefix := proptools.String(module.properties.Jarjar_prefix)
2888	if prefix != "" {
2889		if prefix[0] == '.' {
2890			ctx.PropertyErrorf("jarjar_prefix", "jarjar_prefix can not start with '.'")
2891			return nil
2892		}
2893		if prefix[len(prefix)-1] == '.' {
2894			ctx.PropertyErrorf("jarjar_prefix", "jarjar_prefix can not end with '.'")
2895			return nil
2896		}
2897
2898		var updated map[string]string
2899		for orig, renamed := range (*result).Rename {
2900			if renamed == "" {
2901				if updated == nil {
2902					updated = make(map[string]string)
2903				}
2904				updated[orig] = prefix + "." + orig
2905			}
2906		}
2907		for orig, renamed := range updated {
2908			(*result).Rename[orig] = renamed
2909		}
2910	}
2911
2912	return result
2913}
2914
2915// Get the jarjar rule text for a given provider for the fully resolved rules. Classes that map
2916// to "" won't be in this list because they shouldn't be renamed yet.
2917func getJarJarRuleText(provider *JarJarProviderData) string {
2918	result := strings.Builder{}
2919	for _, orig := range android.SortedKeys(provider.Rename) {
2920		renamed := provider.Rename[orig]
2921		if renamed != "" {
2922			result.WriteString("rule ")
2923			result.WriteString(orig)
2924			result.WriteString(" ")
2925			result.WriteString(renamed)
2926			result.WriteString("\n")
2927		}
2928	}
2929	return result.String()
2930}
2931
2932// Repackage the flags if the jarjar rule txt for the flags is generated
2933func (j *Module) repackageFlagsIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string) (android.Path, bool) {
2934	if j.repackageJarjarRules == nil {
2935		return infile, false
2936	}
2937	repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", info, jarName)
2938	TransformJarJar(ctx, repackagedJarjarFile, infile, j.repackageJarjarRules)
2939	return repackagedJarjarFile, true
2940}
2941
2942func (j *Module) jarjarIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string, useShards bool) (android.Path, bool) {
2943	if j.expandJarjarRules == nil {
2944		return infile, false
2945	}
2946	jarjarFile := android.PathForModuleOut(ctx, "jarjar", info, jarName)
2947
2948	totalShards := 1
2949	if useShards {
2950		totalShardsStr := j.properties.Jarjar_shards.GetOrDefault(ctx, "1")
2951		ts, err := strconv.Atoi(totalShardsStr)
2952		if err != nil {
2953			ctx.PropertyErrorf("jarjar_shards", "jarjar_shards must be an integer represented as a string")
2954			return infile, false
2955		}
2956		totalShards = ts
2957	}
2958	TransformJarJarWithShards(ctx, jarjarFile, infile, j.expandJarjarRules, totalShards)
2959	return jarjarFile, true
2960
2961}
2962
2963func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) {
2964	deps.processorPath = append(deps.processorPath, pluginJars...)
2965	deps.processorClasses = append(deps.processorClasses, pluginClasses...)
2966}
2967
2968// TODO(b/132357300) Generalize SdkLibrarComponentDependency to non-SDK libraries and merge with
2969// this interface.
2970type ProvidesUsesLib interface {
2971	ProvidesUsesLib() *string
2972}
2973
2974func (j *Module) ProvidesUsesLib() *string {
2975	return j.usesLibraryProperties.Provides_uses_lib
2976}
2977
2978type ModuleWithStem interface {
2979	Stem() string
2980}
2981
2982var _ ModuleWithStem = (*Module)(nil)
2983
2984type ModuleWithUsesLibrary interface {
2985	UsesLibrary() *usesLibrary
2986}
2987
2988func (j *Module) UsesLibrary() *usesLibrary {
2989	return &j.usesLibrary
2990}
2991
2992var _ ModuleWithUsesLibrary = (*Module)(nil)
2993