1// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17// This file contains the module types for compiling Java for Android, and converts the properties
18// into the flags and filenames necessary to pass to the Module.  The final creation of the rules
19// is handled in builder.go
20
21import (
22	"fmt"
23	"path/filepath"
24	"strconv"
25	"strings"
26
27	"github.com/google/blueprint"
28	"github.com/google/blueprint/pathtools"
29	"github.com/google/blueprint/proptools"
30
31	"android/soong/android"
32	"android/soong/java/config"
33	"android/soong/tradefed"
34)
35
36func init() {
37	RegisterJavaBuildComponents(android.InitRegistrationContext)
38
39	// Register sdk member types.
40	android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType)
41
42	android.RegisterSdkMemberType(&librarySdkMemberType{
43		android.SdkMemberTypeBase{
44			PropertyName: "java_libs",
45		},
46		func(j *Library) android.Path {
47			implementationJars := j.ImplementationAndResourcesJars()
48			if len(implementationJars) != 1 {
49				panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name()))
50			}
51
52			return implementationJars[0]
53		},
54	})
55
56	android.RegisterSdkMemberType(&testSdkMemberType{
57		SdkMemberTypeBase: android.SdkMemberTypeBase{
58			PropertyName: "java_tests",
59		},
60	})
61}
62
63func RegisterJavaBuildComponents(ctx android.RegistrationContext) {
64	ctx.RegisterModuleType("java_defaults", DefaultsFactory)
65
66	ctx.RegisterModuleType("java_library", LibraryFactory)
67	ctx.RegisterModuleType("java_library_static", LibraryStaticFactory)
68	ctx.RegisterModuleType("java_library_host", LibraryHostFactory)
69	ctx.RegisterModuleType("java_binary", BinaryFactory)
70	ctx.RegisterModuleType("java_binary_host", BinaryHostFactory)
71	ctx.RegisterModuleType("java_test", TestFactory)
72	ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory)
73	ctx.RegisterModuleType("java_test_host", TestHostFactory)
74	ctx.RegisterModuleType("java_test_import", JavaTestImportFactory)
75	ctx.RegisterModuleType("java_import", ImportFactory)
76	ctx.RegisterModuleType("java_import_host", ImportFactoryHost)
77	ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory)
78	ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
79	ctx.RegisterModuleType("dex_import", DexImportFactory)
80
81	ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
82		ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel()
83	})
84
85	ctx.RegisterSingletonType("logtags", LogtagsSingleton)
86	ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
87}
88
89func (j *Module) CheckStableSdkVersion() error {
90	sdkVersion := j.sdkVersion()
91	if sdkVersion.stable() {
92		return nil
93	}
94	return fmt.Errorf("non stable SDK %v", sdkVersion)
95}
96
97func (j *Module) checkSdkVersions(ctx android.ModuleContext) {
98	if j.RequiresStableAPIs(ctx) {
99		if sc, ok := ctx.Module().(sdkContext); ok {
100			if !sc.sdkVersion().specified() {
101				ctx.PropertyErrorf("sdk_version",
102					"sdk_version must have a value when the module is located at vendor or product(only if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is set).")
103			}
104		}
105	}
106
107	ctx.VisitDirectDeps(func(module android.Module) {
108		tag := ctx.OtherModuleDependencyTag(module)
109		switch module.(type) {
110		// TODO(satayev): cover other types as well, e.g. imports
111		case *Library, *AndroidLibrary:
112			switch tag {
113			case bootClasspathTag, libTag, staticLibTag, java9LibTag:
114				checkLinkType(ctx, j, module.(linkTypeContext), tag.(dependencyTag))
115			}
116		}
117	})
118}
119
120func (j *Module) checkPlatformAPI(ctx android.ModuleContext) {
121	if sc, ok := ctx.Module().(sdkContext); ok {
122		usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis)
123		sdkVersionSpecified := sc.sdkVersion().specified()
124		if usePlatformAPI && sdkVersionSpecified {
125			ctx.PropertyErrorf("platform_apis", "platform_apis must be false when sdk_version is not empty.")
126		} else if !usePlatformAPI && !sdkVersionSpecified {
127			ctx.PropertyErrorf("platform_apis", "platform_apis must be true when sdk_version is empty.")
128		}
129
130	}
131}
132
133// TODO:
134// Autogenerated files:
135//  Renderscript
136// Post-jar passes:
137//  Proguard
138// Rmtypedefs
139// DroidDoc
140// Findbugs
141
142type CompilerProperties struct {
143	// list of source files used to compile the Java module.  May be .java, .kt, .logtags, .proto,
144	// or .aidl files.
145	Srcs []string `android:"path,arch_variant"`
146
147	// list Kotlin of source files containing Kotlin code that should be treated as common code in
148	// a codebase that supports Kotlin multiplatform.  See
149	// https://kotlinlang.org/docs/reference/multiplatform.html.  May be only be .kt files.
150	Common_srcs []string `android:"path,arch_variant"`
151
152	// list of source files that should not be used to build the Java module.
153	// This is most useful in the arch/multilib variants to remove non-common files
154	Exclude_srcs []string `android:"path,arch_variant"`
155
156	// list of directories containing Java resources
157	Java_resource_dirs []string `android:"arch_variant"`
158
159	// list of directories that should be excluded from java_resource_dirs
160	Exclude_java_resource_dirs []string `android:"arch_variant"`
161
162	// list of files to use as Java resources
163	Java_resources []string `android:"path,arch_variant"`
164
165	// list of files that should be excluded from java_resources and java_resource_dirs
166	Exclude_java_resources []string `android:"path,arch_variant"`
167
168	// list of module-specific flags that will be used for javac compiles
169	Javacflags []string `android:"arch_variant"`
170
171	// list of module-specific flags that will be used for kotlinc compiles
172	Kotlincflags []string `android:"arch_variant"`
173
174	// list of of java libraries that will be in the classpath
175	Libs []string `android:"arch_variant"`
176
177	// list of java libraries that will be compiled into the resulting jar
178	Static_libs []string `android:"arch_variant"`
179
180	// manifest file to be included in resulting jar
181	Manifest *string `android:"path"`
182
183	// if not blank, run jarjar using the specified rules file
184	Jarjar_rules *string `android:"path,arch_variant"`
185
186	// If not blank, set the java version passed to javac as -source and -target
187	Java_version *string
188
189	// If set to true, allow this module to be dexed and installed on devices.  Has no
190	// effect on host modules, which are always considered installable.
191	Installable *bool
192
193	// If set to true, include sources used to compile the module in to the final jar
194	Include_srcs *bool
195
196	// If not empty, classes are restricted to the specified packages and their sub-packages.
197	// This restriction is checked after applying jarjar rules and including static libs.
198	Permitted_packages []string
199
200	// List of modules to use as annotation processors
201	Plugins []string
202
203	// List of modules to export to libraries that directly depend on this library as annotation processors
204	Exported_plugins []string
205
206	// The number of Java source entries each Javac instance can process
207	Javac_shard_size *int64
208
209	// Add host jdk tools.jar to bootclasspath
210	Use_tools_jar *bool
211
212	Openjdk9 struct {
213		// List of source files that should only be used when passing -source 1.9 or higher
214		Srcs []string `android:"path"`
215
216		// List of javac flags that should only be used when passing -source 1.9 or higher
217		Javacflags []string
218	}
219
220	// When compiling language level 9+ .java code in packages that are part of
221	// a system module, patch_module names the module that your sources and
222	// dependencies should be patched into. The Android runtime currently
223	// doesn't implement the JEP 261 module system so this option is only
224	// supported at compile time. It should only be needed to compile tests in
225	// packages that exist in libcore and which are inconvenient to move
226	// elsewhere.
227	Patch_module *string `android:"arch_variant"`
228
229	Jacoco struct {
230		// List of classes to include for instrumentation with jacoco to collect coverage
231		// information at runtime when building with coverage enabled.  If unset defaults to all
232		// classes.
233		// Supports '*' as the last character of an entry in the list as a wildcard match.
234		// If preceded by '.' it matches all classes in the package and subpackages, otherwise
235		// it matches classes in the package that have the class name as a prefix.
236		Include_filter []string
237
238		// List of classes to exclude from instrumentation with jacoco to collect coverage
239		// information at runtime when building with coverage enabled.  Overrides classes selected
240		// by the include_filter property.
241		// Supports '*' as the last character of an entry in the list as a wildcard match.
242		// If preceded by '.' it matches all classes in the package and subpackages, otherwise
243		// it matches classes in the package that have the class name as a prefix.
244		Exclude_filter []string
245	}
246
247	Errorprone struct {
248		// List of javac flags that should only be used when running errorprone.
249		Javacflags []string
250	}
251
252	Proto struct {
253		// List of extra options that will be passed to the proto generator.
254		Output_params []string
255	}
256
257	Instrument bool `blueprint:"mutated"`
258
259	// List of files to include in the META-INF/services folder of the resulting jar.
260	Services []string `android:"path,arch_variant"`
261
262	// If true, package the kotlin stdlib into the jar.  Defaults to true.
263	Static_kotlin_stdlib *bool `android:"arch_variant"`
264}
265
266type CompilerDeviceProperties struct {
267	// list of module-specific flags that will be used for dex compiles
268	Dxflags []string `android:"arch_variant"`
269
270	// if not blank, set to the version of the sdk to compile against.
271	// Defaults to compiling against the current platform.
272	Sdk_version *string
273
274	// if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
275	// Defaults to sdk_version if not set.
276	Min_sdk_version *string
277
278	// if not blank, set the targetSdkVersion in the AndroidManifest.xml.
279	// Defaults to sdk_version if not set.
280	Target_sdk_version *string
281
282	// Whether to compile against the platform APIs instead of an SDK.
283	// If true, then sdk_version must be empty. The value of this field
284	// is ignored when module's type isn't android_app.
285	Platform_apis *bool
286
287	Aidl struct {
288		// Top level directories to pass to aidl tool
289		Include_dirs []string
290
291		// Directories rooted at the Android.bp file to pass to aidl tool
292		Local_include_dirs []string
293
294		// directories that should be added as include directories for any aidl sources of modules
295		// that depend on this module, as well as to aidl for this module.
296		Export_include_dirs []string
297
298		// whether to generate traces (for systrace) for this interface
299		Generate_traces *bool
300
301		// whether to generate Binder#GetTransaction name method.
302		Generate_get_transaction_name *bool
303	}
304
305	// If true, export a copy of the module as a -hostdex module for host testing.
306	Hostdex *bool
307
308	Target struct {
309		Hostdex struct {
310			// Additional required dependencies to add to -hostdex modules.
311			Required []string
312		}
313	}
314
315	// If set to true, compile dex regardless of installable.  Defaults to false.
316	Compile_dex *bool
317
318	Optimize struct {
319		// If false, disable all optimization.  Defaults to true for android_app and android_test
320		// modules, false for java_library and java_test modules.
321		Enabled *bool
322		// True if the module containing this has it set by default.
323		EnabledByDefault bool `blueprint:"mutated"`
324
325		// If true, optimize for size by removing unused code.  Defaults to true for apps,
326		// false for libraries and tests.
327		Shrink *bool
328
329		// If true, optimize bytecode.  Defaults to false.
330		Optimize *bool
331
332		// If true, obfuscate bytecode.  Defaults to false.
333		Obfuscate *bool
334
335		// If true, do not use the flag files generated by aapt that automatically keep
336		// classes referenced by the app manifest.  Defaults to false.
337		No_aapt_flags *bool
338
339		// Flags to pass to proguard.
340		Proguard_flags []string
341
342		// Specifies the locations of files containing proguard flags.
343		Proguard_flags_files []string `android:"path"`
344	}
345
346	// When targeting 1.9 and above, override the modules to use with --system,
347	// otherwise provides defaults libraries to add to the bootclasspath.
348	System_modules *string
349
350	// The name of the module as used in build configuration.
351	//
352	// Allows a library to separate its actual name from the name used in
353	// build configuration, e.g.ctx.Config().BootJars().
354	ConfigurationName *string `blueprint:"mutated"`
355
356	// set the name of the output
357	Stem *string
358
359	// Keep the data uncompressed. We always need uncompressed dex for execution,
360	// so this might actually save space by avoiding storing the same data twice.
361	// This defaults to reasonable value based on module and should not be set.
362	// It exists only to support ART tests.
363	Uncompress_dex *bool
364
365	IsSDKLibrary bool `blueprint:"mutated"`
366}
367
368func (me *CompilerDeviceProperties) EffectiveOptimizeEnabled() bool {
369	return BoolDefault(me.Optimize.Enabled, me.Optimize.EnabledByDefault)
370}
371
372// Functionality common to Module and Import
373//
374// It is embedded in Module so its functionality can be used by methods in Module
375// but it is currently only initialized by Import and Library.
376type embeddableInModuleAndImport struct {
377
378	// Functionality related to this being used as a component of a java_sdk_library.
379	EmbeddableSdkLibraryComponent
380}
381
382func (e *embeddableInModuleAndImport) initModuleAndImport(moduleBase *android.ModuleBase) {
383	e.initSdkLibraryComponent(moduleBase)
384}
385
386// Module/Import's DepIsInSameApex(...) delegates to this method.
387//
388// This cannot implement DepIsInSameApex(...) directly as that leads to ambiguity with
389// the one provided by ApexModuleBase.
390func (e *embeddableInModuleAndImport) depIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
391	// dependencies other than the static linkage are all considered crossing APEX boundary
392	if staticLibTag == ctx.OtherModuleDependencyTag(dep) {
393		return true
394	}
395	return false
396}
397
398// Module contains the properties and members used by all java module types
399type Module struct {
400	android.ModuleBase
401	android.DefaultableModuleBase
402	android.ApexModuleBase
403	android.SdkBase
404
405	// Functionality common to Module and Import.
406	embeddableInModuleAndImport
407
408	properties       CompilerProperties
409	protoProperties  android.ProtoProperties
410	deviceProperties CompilerDeviceProperties
411
412	// jar file containing header classes including static library dependencies, suitable for
413	// inserting into the bootclasspath/classpath of another compile
414	headerJarFile android.Path
415
416	// jar file containing implementation classes including static library dependencies but no
417	// resources
418	implementationJarFile android.Path
419
420	// jar file containing only resources including from static library dependencies
421	resourceJar android.Path
422
423	// args and dependencies to package source files into a srcjar
424	srcJarArgs []string
425	srcJarDeps android.Paths
426
427	// jar file containing implementation classes and resources including static library
428	// dependencies
429	implementationAndResourcesJar android.Path
430
431	// output file containing classes.dex and resources
432	dexJarFile android.Path
433
434	// output file that contains classes.dex if it should be in the output file
435	maybeStrippedDexJarFile android.Path
436
437	// output file containing uninstrumented classes that will be instrumented by jacoco
438	jacocoReportClassesFile android.Path
439
440	// output file containing mapping of obfuscated names
441	proguardDictionary android.Path
442
443	// output file of the module, which may be a classes jar or a dex jar
444	outputFile       android.Path
445	extraOutputFiles android.Paths
446
447	exportAidlIncludeDirs android.Paths
448
449	logtagsSrcs android.Paths
450
451	// installed file for binary dependency
452	installFile android.Path
453
454	// list of .java files and srcjars that was passed to javac
455	compiledJavaSrcs android.Paths
456	compiledSrcJars  android.Paths
457
458	// list of extra progurad flag files
459	extraProguardFlagFiles android.Paths
460
461	// manifest file to use instead of properties.Manifest
462	overrideManifest android.OptionalPath
463
464	// list of SDK lib names that this java module is exporting
465	exportedSdkLibs []string
466
467	// list of plugins that this java module is exporting
468	exportedPluginJars android.Paths
469
470	// list of plugins that this java module is exporting
471	exportedPluginClasses []string
472
473	// list of source files, collected from srcFiles with unique java and all kt files,
474	// will be used by android.IDEInfo struct
475	expandIDEInfoCompiledSrcs []string
476
477	// expanded Jarjar_rules
478	expandJarjarRules android.Path
479
480	// list of additional targets for checkbuild
481	additionalCheckedModules android.Paths
482
483	// Extra files generated by the module type to be added as java resources.
484	extraResources android.Paths
485
486	hiddenAPI
487	dexpreopter
488	linter
489
490	// list of the xref extraction files
491	kytheFiles android.Paths
492
493	distFiles android.TaggedDistFiles
494
495	// Collect the module directory for IDE info in java/jdeps.go.
496	modulePaths []string
497}
498
499func (j *Module) addHostProperties() {
500	j.AddProperties(
501		&j.properties,
502		&j.protoProperties,
503	)
504}
505
506func (j *Module) addHostAndDeviceProperties() {
507	j.addHostProperties()
508	j.AddProperties(
509		&j.deviceProperties,
510		&j.dexpreoptProperties,
511		&j.linter.properties,
512	)
513}
514
515func (j *Module) OutputFiles(tag string) (android.Paths, error) {
516	switch tag {
517	case "":
518		return append(android.Paths{j.outputFile}, j.extraOutputFiles...), nil
519	case ".jar":
520		return android.Paths{j.implementationAndResourcesJar}, nil
521	case ".proguard_map":
522		return android.Paths{j.proguardDictionary}, nil
523	default:
524		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
525	}
526}
527
528var _ android.OutputFileProducer = (*Module)(nil)
529
530// Methods that need to be implemented for a module that is added to apex java_libs property.
531type ApexDependency interface {
532	HeaderJars() android.Paths
533	ImplementationAndResourcesJars() android.Paths
534}
535
536type Dependency interface {
537	ApexDependency
538	ImplementationJars() android.Paths
539	ResourceJars() android.Paths
540	DexJarBuildPath() android.Path
541	DexJarInstallPath() android.Path
542	AidlIncludeDirs() android.Paths
543	ExportedSdkLibs() []string
544	ExportedPlugins() (android.Paths, []string)
545	SrcJarArgs() ([]string, android.Paths)
546	BaseModuleName() string
547	JacocoReportClassesFile() android.Path
548}
549
550type xref interface {
551	XrefJavaFiles() android.Paths
552}
553
554func (j *Module) XrefJavaFiles() android.Paths {
555	return j.kytheFiles
556}
557
558func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
559	initJavaModule(module, hod, false)
560}
561
562func InitJavaModuleMultiTargets(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
563	initJavaModule(module, hod, true)
564}
565
566func initJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported, multiTargets bool) {
567	multilib := android.MultilibCommon
568	if multiTargets {
569		android.InitAndroidMultiTargetsArchModule(module, hod, multilib)
570	} else {
571		android.InitAndroidArchModule(module, hod, multilib)
572	}
573	android.InitDefaultableModule(module)
574}
575
576type dependencyTag struct {
577	blueprint.BaseDependencyTag
578	name string
579}
580
581type jniDependencyTag struct {
582	blueprint.BaseDependencyTag
583}
584
585func IsJniDepTag(depTag blueprint.DependencyTag) bool {
586	_, ok := depTag.(*jniDependencyTag)
587	return ok
588}
589
590var (
591	dataNativeBinsTag     = dependencyTag{name: "dataNativeBins"}
592	staticLibTag          = dependencyTag{name: "staticlib"}
593	libTag                = dependencyTag{name: "javalib"}
594	java9LibTag           = dependencyTag{name: "java9lib"}
595	pluginTag             = dependencyTag{name: "plugin"}
596	exportedPluginTag     = dependencyTag{name: "exported-plugin"}
597	bootClasspathTag      = dependencyTag{name: "bootclasspath"}
598	systemModulesTag      = dependencyTag{name: "system modules"}
599	frameworkResTag       = dependencyTag{name: "framework-res"}
600	frameworkApkTag       = dependencyTag{name: "framework-apk"}
601	kotlinStdlibTag       = dependencyTag{name: "kotlin-stdlib"}
602	kotlinAnnotationsTag  = dependencyTag{name: "kotlin-annotations"}
603	proguardRaiseTag      = dependencyTag{name: "proguard-raise"}
604	certificateTag        = dependencyTag{name: "certificate"}
605	instrumentationForTag = dependencyTag{name: "instrumentation_for"}
606	usesLibTag            = dependencyTag{name: "uses-library"}
607	extraLintCheckTag     = dependencyTag{name: "extra-lint-check"}
608)
609
610func IsLibDepTag(depTag blueprint.DependencyTag) bool {
611	return depTag == libTag
612}
613
614func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool {
615	return depTag == staticLibTag
616}
617
618type sdkDep struct {
619	useModule, useFiles, invalidVersion bool
620
621	// The modules that will be added to the bootclasspath when targeting 1.8 or lower
622	bootclasspath []string
623
624	// The default system modules to use. Will be an empty string if no system
625	// modules are to be used.
626	systemModules string
627
628	// The modules that will be added to the classpath regardless of the Java language level targeted
629	classpath []string
630
631	// The modules that will be added ot the classpath when targeting 1.9 or higher
632	// (normally these will be on the bootclasspath when targeting 1.8 or lower)
633	java9Classpath []string
634
635	frameworkResModule string
636
637	jars android.Paths
638	aidl android.OptionalPath
639
640	noStandardLibs, noFrameworksLibs bool
641}
642
643func (s sdkDep) hasStandardLibs() bool {
644	return !s.noStandardLibs
645}
646
647func (s sdkDep) hasFrameworkLibs() bool {
648	return !s.noStandardLibs && !s.noFrameworksLibs
649}
650
651type jniLib struct {
652	name           string
653	path           android.Path
654	target         android.Target
655	coverageFile   android.OptionalPath
656	unstrippedFile android.Path
657}
658
659func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool {
660	return j.properties.Instrument &&
661		ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") &&
662		ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir())
663}
664
665func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool {
666	return j.shouldInstrument(ctx) &&
667		(ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_STATIC") ||
668			ctx.Config().UnbundledBuild())
669}
670
671func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool {
672	// Force enable the instrumentation for java code that is built for APEXes ...
673	// except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent
674	// doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true.
675	isJacocoAgent := ctx.ModuleName() == "jacocoagent"
676	if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !isJacocoAgent && !j.IsForPlatform() {
677		if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
678			return true
679		} else if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
680			return true
681		}
682	}
683	return false
684}
685
686func (j *Module) sdkVersion() sdkSpec {
687	return sdkSpecFrom(String(j.deviceProperties.Sdk_version))
688}
689
690func (j *Module) systemModules() string {
691	return proptools.String(j.deviceProperties.System_modules)
692}
693
694func (j *Module) minSdkVersion() sdkSpec {
695	if j.deviceProperties.Min_sdk_version != nil {
696		return sdkSpecFrom(*j.deviceProperties.Min_sdk_version)
697	}
698	return j.sdkVersion()
699}
700
701func (j *Module) targetSdkVersion() sdkSpec {
702	if j.deviceProperties.Target_sdk_version != nil {
703		return sdkSpecFrom(*j.deviceProperties.Target_sdk_version)
704	}
705	return j.sdkVersion()
706}
707
708func (j *Module) MinSdkVersion() string {
709	return j.minSdkVersion().version.String()
710}
711
712func (j *Module) AvailableFor(what string) bool {
713	if what == android.AvailableToPlatform && Bool(j.deviceProperties.Hostdex) {
714		// Exception: for hostdex: true libraries, the platform variant is created
715		// even if it's not marked as available to platform. In that case, the platform
716		// variant is used only for the hostdex and not installed to the device.
717		return true
718	}
719	return j.ApexModuleBase.AvailableFor(what)
720}
721
722func (j *Module) deps(ctx android.BottomUpMutatorContext) {
723	if ctx.Device() {
724		j.linter.deps(ctx)
725
726		sdkDep := decodeSdkDep(ctx, sdkContext(j))
727		if sdkDep.useModule {
728			ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
729			ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
730			ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...)
731			if j.deviceProperties.EffectiveOptimizeEnabled() && sdkDep.hasStandardLibs() {
732				ctx.AddVariationDependencies(nil, proguardRaiseTag, config.LegacyCorePlatformBootclasspathLibraries...)
733			}
734			if j.deviceProperties.EffectiveOptimizeEnabled() && sdkDep.hasFrameworkLibs() {
735				ctx.AddVariationDependencies(nil, proguardRaiseTag, config.FrameworkLibraries...)
736			}
737		}
738		if sdkDep.systemModules != "" {
739			ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
740		}
741
742		if ctx.ModuleName() == "android_stubs_current" ||
743			ctx.ModuleName() == "android_system_stubs_current" ||
744			ctx.ModuleName() == "android_test_stubs_current" {
745			ctx.AddVariationDependencies(nil, frameworkApkTag, "framework-res")
746		}
747	}
748
749	syspropPublicStubs := syspropPublicStubs(ctx.Config())
750
751	// rewriteSyspropLibs validates if a java module can link against platform's sysprop_library,
752	// and redirects dependency to public stub depending on the link type.
753	rewriteSyspropLibs := func(libs []string, prop string) []string {
754		// make a copy
755		ret := android.CopyOf(libs)
756
757		for idx, lib := range libs {
758			stub, ok := syspropPublicStubs[lib]
759
760			if !ok {
761				continue
762			}
763
764			linkType, _ := j.getLinkType(ctx.ModuleName())
765			// only platform modules can use internal props
766			if linkType != javaPlatform {
767				ret[idx] = stub
768			}
769		}
770
771		return ret
772	}
773
774	ctx.AddVariationDependencies(nil, libTag, rewriteSyspropLibs(j.properties.Libs, "libs")...)
775	ctx.AddVariationDependencies(nil, staticLibTag, rewriteSyspropLibs(j.properties.Static_libs, "static_libs")...)
776
777	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...)
778	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...)
779
780	android.ProtoDeps(ctx, &j.protoProperties)
781	if j.hasSrcExt(".proto") {
782		protoDeps(ctx, &j.protoProperties)
783	}
784
785	if j.hasSrcExt(".kt") {
786		// TODO(ccross): move this to a mutator pass that can tell if generated sources contain
787		// Kotlin files
788		ctx.AddVariationDependencies(nil, kotlinStdlibTag,
789			"kotlin-stdlib", "kotlin-stdlib-jdk7", "kotlin-stdlib-jdk8")
790		if len(j.properties.Plugins) > 0 {
791			ctx.AddVariationDependencies(nil, kotlinAnnotationsTag, "kotlin-annotations")
792		}
793	}
794
795	// Framework libraries need special handling in static coverage builds: they should not have
796	// static dependency on jacoco, otherwise there would be multiple conflicting definitions of
797	// the same jacoco classes coming from different bootclasspath jars.
798	if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
799		if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
800			j.properties.Instrument = true
801		}
802	} else if j.shouldInstrumentStatic(ctx) {
803		ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
804	}
805}
806
807func hasSrcExt(srcs []string, ext string) bool {
808	for _, src := range srcs {
809		if filepath.Ext(src) == ext {
810			return true
811		}
812	}
813
814	return false
815}
816
817func (j *Module) hasSrcExt(ext string) bool {
818	return hasSrcExt(j.properties.Srcs, ext)
819}
820
821func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
822	aidlIncludeDirs android.Paths) (string, android.Paths) {
823
824	aidlIncludes := android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Local_include_dirs)
825	aidlIncludes = append(aidlIncludes,
826		android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)...)
827	aidlIncludes = append(aidlIncludes,
828		android.PathsForSource(ctx, j.deviceProperties.Aidl.Include_dirs)...)
829
830	var flags []string
831	var deps android.Paths
832
833	if aidlPreprocess.Valid() {
834		flags = append(flags, "-p"+aidlPreprocess.String())
835		deps = append(deps, aidlPreprocess.Path())
836	} else if len(aidlIncludeDirs) > 0 {
837		flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
838	}
839
840	if len(j.exportAidlIncludeDirs) > 0 {
841		flags = append(flags, android.JoinWithPrefix(j.exportAidlIncludeDirs.Strings(), "-I"))
842	}
843
844	if len(aidlIncludes) > 0 {
845		flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
846	}
847
848	flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
849	if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
850		flags = append(flags, "-I"+src.String())
851	}
852
853	if Bool(j.deviceProperties.Aidl.Generate_traces) {
854		flags = append(flags, "-t")
855	}
856
857	if Bool(j.deviceProperties.Aidl.Generate_get_transaction_name) {
858		flags = append(flags, "--transaction_names")
859	}
860
861	return strings.Join(flags, " "), deps
862}
863
864type deps struct {
865	classpath          classpath
866	java9Classpath     classpath
867	bootClasspath      classpath
868	processorPath      classpath
869	processorClasses   []string
870	staticJars         android.Paths
871	staticHeaderJars   android.Paths
872	staticResourceJars android.Paths
873	aidlIncludeDirs    android.Paths
874	srcs               android.Paths
875	srcJars            android.Paths
876	systemModules      *systemModules
877	aidlPreprocess     android.OptionalPath
878	kotlinStdlib       android.Paths
879	kotlinAnnotations  android.Paths
880
881	disableTurbine bool
882}
883
884func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) {
885	for _, f := range dep.Srcs() {
886		if f.Ext() != ".jar" {
887			ctx.ModuleErrorf("genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency",
888				ctx.OtherModuleName(dep.(blueprint.Module)))
889		}
890	}
891}
892
893type linkType int
894
895const (
896	// TODO(jiyong) rename these for better readability. Make the allowed
897	// and disallowed link types explicit
898	javaCore linkType = iota
899	javaSdk
900	javaSystem
901	javaModule
902	javaSystemServer
903	javaPlatform
904)
905
906type linkTypeContext interface {
907	android.Module
908	getLinkType(name string) (ret linkType, stubs bool)
909}
910
911func (m *Module) getLinkType(name string) (ret linkType, stubs bool) {
912	switch name {
913	case "core.current.stubs", "legacy.core.platform.api.stubs", "stable.core.platform.api.stubs",
914		"stub-annotations", "private-stub-annotations-jar",
915		"core-lambda-stubs", "core-generated-annotation-stubs":
916		return javaCore, true
917	case "android_stubs_current":
918		return javaSdk, true
919	case "android_system_stubs_current":
920		return javaSystem, true
921	case "android_module_lib_stubs_current":
922		return javaModule, true
923	case "android_system_server_stubs_current":
924		return javaSystemServer, true
925	case "android_test_stubs_current":
926		return javaSystem, true
927	}
928
929	if stub, linkType := moduleStubLinkType(name); stub {
930		return linkType, true
931	}
932
933	ver := m.sdkVersion()
934	switch ver.kind {
935	case sdkCore:
936		return javaCore, false
937	case sdkSystem:
938		return javaSystem, false
939	case sdkPublic:
940		return javaSdk, false
941	case sdkModule:
942		return javaModule, false
943	case sdkSystemServer:
944		return javaSystemServer, false
945	case sdkPrivate, sdkNone, sdkCorePlatform, sdkTest:
946		return javaPlatform, false
947	}
948
949	if !ver.valid() {
950		panic(fmt.Errorf("sdk_version is invalid. got %q", ver.raw))
951	}
952	return javaSdk, false
953}
954
955func checkLinkType(ctx android.ModuleContext, from *Module, to linkTypeContext, tag dependencyTag) {
956	if ctx.Host() {
957		return
958	}
959
960	myLinkType, stubs := from.getLinkType(ctx.ModuleName())
961	if stubs {
962		return
963	}
964	otherLinkType, _ := to.getLinkType(ctx.OtherModuleName(to))
965	commonMessage := "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source."
966
967	switch myLinkType {
968	case javaCore:
969		if otherLinkType != javaCore {
970			ctx.ModuleErrorf("compiles against core Java API, but dependency %q is compiling against non-core Java APIs."+commonMessage,
971				ctx.OtherModuleName(to))
972		}
973		break
974	case javaSdk:
975		if otherLinkType != javaCore && otherLinkType != javaSdk {
976			ctx.ModuleErrorf("compiles against Android API, but dependency %q is compiling against non-public Android API."+commonMessage,
977				ctx.OtherModuleName(to))
978		}
979		break
980	case javaSystem:
981		if otherLinkType == javaPlatform || otherLinkType == javaModule || otherLinkType == javaSystemServer {
982			ctx.ModuleErrorf("compiles against system API, but dependency %q is compiling against private API."+commonMessage,
983				ctx.OtherModuleName(to))
984		}
985		break
986	case javaModule:
987		if otherLinkType == javaPlatform || otherLinkType == javaSystemServer {
988			ctx.ModuleErrorf("compiles against module API, but dependency %q is compiling against private API."+commonMessage,
989				ctx.OtherModuleName(to))
990		}
991		break
992	case javaSystemServer:
993		if otherLinkType == javaPlatform {
994			ctx.ModuleErrorf("compiles against system server API, but dependency %q is compiling against private API."+commonMessage,
995				ctx.OtherModuleName(to))
996		}
997		break
998	case javaPlatform:
999		// no restriction on link-type
1000		break
1001	}
1002}
1003
1004func (j *Module) collectDeps(ctx android.ModuleContext) deps {
1005	var deps deps
1006
1007	if ctx.Device() {
1008		sdkDep := decodeSdkDep(ctx, sdkContext(j))
1009		if sdkDep.invalidVersion {
1010			ctx.AddMissingDependencies(sdkDep.bootclasspath)
1011			ctx.AddMissingDependencies(sdkDep.java9Classpath)
1012		} else if sdkDep.useFiles {
1013			// sdkDep.jar is actually equivalent to turbine header.jar.
1014			deps.classpath = append(deps.classpath, sdkDep.jars...)
1015			deps.aidlPreprocess = sdkDep.aidl
1016		} else {
1017			deps.aidlPreprocess = sdkDep.aidl
1018		}
1019	}
1020
1021	// If this is a component library (stubs, etc.) for a java_sdk_library then
1022	// add the name of that java_sdk_library to the exported sdk libs to make sure
1023	// that, if necessary, a <uses-library> element for that java_sdk_library is
1024	// added to the Android manifest.
1025	j.exportedSdkLibs = append(j.exportedSdkLibs, j.OptionalImplicitSdkLibrary()...)
1026
1027	ctx.VisitDirectDeps(func(module android.Module) {
1028		otherName := ctx.OtherModuleName(module)
1029		tag := ctx.OtherModuleDependencyTag(module)
1030
1031		if _, ok := tag.(*jniDependencyTag); ok {
1032			// Handled by AndroidApp.collectAppDeps
1033			return
1034		}
1035		if tag == certificateTag {
1036			// Handled by AndroidApp.collectAppDeps
1037			return
1038		}
1039
1040		switch dep := module.(type) {
1041		case SdkLibraryDependency:
1042			switch tag {
1043			case libTag:
1044				deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
1045				// names of sdk libs that are directly depended are exported
1046				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.OptionalImplicitSdkLibrary()...)
1047			case staticLibTag:
1048				ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
1049			}
1050		case Dependency:
1051			switch tag {
1052			case bootClasspathTag:
1053				deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
1054			case libTag, instrumentationForTag:
1055				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
1056				// sdk lib names from dependencies are re-exported
1057				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
1058				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
1059				pluginJars, pluginClasses := dep.ExportedPlugins()
1060				addPlugins(&deps, pluginJars, pluginClasses...)
1061			case java9LibTag:
1062				deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars()...)
1063			case staticLibTag:
1064				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
1065				deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
1066				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
1067				deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars()...)
1068				// sdk lib names from dependencies are re-exported
1069				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
1070				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
1071				pluginJars, pluginClasses := dep.ExportedPlugins()
1072				addPlugins(&deps, pluginJars, pluginClasses...)
1073			case pluginTag:
1074				if plugin, ok := dep.(*Plugin); ok {
1075					if plugin.pluginProperties.Processor_class != nil {
1076						addPlugins(&deps, plugin.ImplementationAndResourcesJars(), *plugin.pluginProperties.Processor_class)
1077					} else {
1078						addPlugins(&deps, plugin.ImplementationAndResourcesJars())
1079					}
1080					deps.disableTurbine = deps.disableTurbine || Bool(plugin.pluginProperties.Generates_api)
1081				} else {
1082					ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
1083				}
1084			case exportedPluginTag:
1085				if plugin, ok := dep.(*Plugin); ok {
1086					if plugin.pluginProperties.Generates_api != nil && *plugin.pluginProperties.Generates_api {
1087						ctx.PropertyErrorf("exported_plugins", "Cannot export plugins with generates_api = true, found %v", otherName)
1088					}
1089					j.exportedPluginJars = append(j.exportedPluginJars, plugin.ImplementationAndResourcesJars()...)
1090					if plugin.pluginProperties.Processor_class != nil {
1091						j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.pluginProperties.Processor_class)
1092					}
1093				} else {
1094					ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName)
1095				}
1096			case frameworkApkTag:
1097				if ctx.ModuleName() == "android_stubs_current" ||
1098					ctx.ModuleName() == "android_system_stubs_current" ||
1099					ctx.ModuleName() == "android_test_stubs_current" {
1100					// framework stubs.jar need to depend on framework-res.apk, in order to pull the
1101					// resource files out of there for aapt.
1102					//
1103					// Normally the package rule runs aapt, which includes the resource,
1104					// but we're not running that in our package rule so just copy in the
1105					// resource files here.
1106					deps.staticResourceJars = append(deps.staticResourceJars, dep.(*AndroidApp).exportPackage)
1107				}
1108			case kotlinStdlibTag:
1109				deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars()...)
1110			case kotlinAnnotationsTag:
1111				deps.kotlinAnnotations = dep.HeaderJars()
1112			}
1113
1114		case android.SourceFileProducer:
1115			switch tag {
1116			case libTag:
1117				checkProducesJars(ctx, dep)
1118				deps.classpath = append(deps.classpath, dep.Srcs()...)
1119			case staticLibTag:
1120				checkProducesJars(ctx, dep)
1121				deps.classpath = append(deps.classpath, dep.Srcs()...)
1122				deps.staticJars = append(deps.staticJars, dep.Srcs()...)
1123				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
1124			}
1125		default:
1126			switch tag {
1127			case bootClasspathTag:
1128				// If a system modules dependency has been added to the bootclasspath
1129				// then add its libs to the bootclasspath.
1130				sm := module.(SystemModulesProvider)
1131				deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars()...)
1132
1133			case systemModulesTag:
1134				if deps.systemModules != nil {
1135					panic("Found two system module dependencies")
1136				}
1137				sm := module.(SystemModulesProvider)
1138				outputDir, outputDeps := sm.OutputDirAndDeps()
1139				deps.systemModules = &systemModules{outputDir, outputDeps}
1140			}
1141		}
1142	})
1143
1144	j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)
1145
1146	return deps
1147}
1148
1149func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) {
1150	deps.processorPath = append(deps.processorPath, pluginJars...)
1151	deps.processorClasses = append(deps.processorClasses, pluginClasses...)
1152}
1153
1154func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) javaVersion {
1155	if javaVersion != "" {
1156		return normalizeJavaVersion(ctx, javaVersion)
1157	} else if ctx.Device() {
1158		return sdkContext.sdkVersion().defaultJavaLanguageVersion(ctx)
1159	} else {
1160		return JAVA_VERSION_9
1161	}
1162}
1163
1164type javaVersion int
1165
1166const (
1167	JAVA_VERSION_UNSUPPORTED = 0
1168	JAVA_VERSION_6           = 6
1169	JAVA_VERSION_7           = 7
1170	JAVA_VERSION_8           = 8
1171	JAVA_VERSION_9           = 9
1172)
1173
1174func (v javaVersion) String() string {
1175	switch v {
1176	case JAVA_VERSION_6:
1177		return "1.6"
1178	case JAVA_VERSION_7:
1179		return "1.7"
1180	case JAVA_VERSION_8:
1181		return "1.8"
1182	case JAVA_VERSION_9:
1183		return "1.9"
1184	default:
1185		return "unsupported"
1186	}
1187}
1188
1189// Returns true if javac targeting this version uses system modules instead of a bootclasspath.
1190func (v javaVersion) usesJavaModules() bool {
1191	return v >= 9
1192}
1193
1194func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) javaVersion {
1195	switch javaVersion {
1196	case "1.6", "6":
1197		return JAVA_VERSION_6
1198	case "1.7", "7":
1199		return JAVA_VERSION_7
1200	case "1.8", "8":
1201		return JAVA_VERSION_8
1202	case "1.9", "9":
1203		return JAVA_VERSION_9
1204	case "10", "11":
1205		ctx.PropertyErrorf("java_version", "Java language levels above 9 are not supported")
1206		return JAVA_VERSION_UNSUPPORTED
1207	default:
1208		ctx.PropertyErrorf("java_version", "Unrecognized Java language level")
1209		return JAVA_VERSION_UNSUPPORTED
1210	}
1211}
1212
1213func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags {
1214
1215	var flags javaBuilderFlags
1216
1217	// javaVersion flag.
1218	flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
1219
1220	// javac flags.
1221	javacFlags := j.properties.Javacflags
1222	if flags.javaVersion.usesJavaModules() {
1223		javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
1224	}
1225	if ctx.Config().MinimizeJavaDebugInfo() && !ctx.Host() {
1226		// For non-host binaries, override the -g flag passed globally to remove
1227		// local variable debug info to reduce disk and memory usage.
1228		javacFlags = append(javacFlags, "-g:source,lines")
1229	}
1230	javacFlags = append(javacFlags, "-Xlint:-dep-ann")
1231
1232	if ctx.Config().RunErrorProne() {
1233		if config.ErrorProneClasspath == nil {
1234			ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
1235		}
1236
1237		errorProneFlags := []string{
1238			"-Xplugin:ErrorProne",
1239			"${config.ErrorProneChecks}",
1240		}
1241		errorProneFlags = append(errorProneFlags, j.properties.Errorprone.Javacflags...)
1242
1243		flags.errorProneExtraJavacFlags = "${config.ErrorProneFlags} " +
1244			"'" + strings.Join(errorProneFlags, " ") + "'"
1245		flags.errorProneProcessorPath = classpath(android.PathsForSource(ctx, config.ErrorProneClasspath))
1246	}
1247
1248	// classpath
1249	flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...)
1250	flags.classpath = append(flags.classpath, deps.classpath...)
1251	flags.java9Classpath = append(flags.java9Classpath, deps.java9Classpath...)
1252	flags.processorPath = append(flags.processorPath, deps.processorPath...)
1253
1254	flags.processors = append(flags.processors, deps.processorClasses...)
1255	flags.processors = android.FirstUniqueStrings(flags.processors)
1256
1257	if len(flags.bootClasspath) == 0 && ctx.Host() && !flags.javaVersion.usesJavaModules() &&
1258		decodeSdkDep(ctx, sdkContext(j)).hasStandardLibs() {
1259		// Give host-side tools a version of OpenJDK's standard libraries
1260		// close to what they're targeting. As of Dec 2017, AOSP is only
1261		// bundling OpenJDK 8 and 9, so nothing < 8 is available.
1262		//
1263		// When building with OpenJDK 8, the following should have no
1264		// effect since those jars would be available by default.
1265		//
1266		// When building with OpenJDK 9 but targeting a version < 1.8,
1267		// putting them on the bootclasspath means that:
1268		// a) code can't (accidentally) refer to OpenJDK 9 specific APIs
1269		// b) references to existing APIs are not reinterpreted in an
1270		//    OpenJDK 9-specific way, eg. calls to subclasses of
1271		//    java.nio.Buffer as in http://b/70862583
1272		java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1273		flags.bootClasspath = append(flags.bootClasspath,
1274			android.PathForSource(ctx, java8Home, "jre/lib/jce.jar"),
1275			android.PathForSource(ctx, java8Home, "jre/lib/rt.jar"))
1276		if Bool(j.properties.Use_tools_jar) {
1277			flags.bootClasspath = append(flags.bootClasspath,
1278				android.PathForSource(ctx, java8Home, "lib/tools.jar"))
1279		}
1280	}
1281
1282	if j.properties.Patch_module != nil && flags.javaVersion.usesJavaModules() {
1283		// Manually specify build directory in case it is not under the repo root.
1284		// (javac doesn't seem to expand into symbolc links when searching for patch-module targets, so
1285		// just adding a symlink under the root doesn't help.)
1286		patchPaths := ".:" + ctx.Config().BuildDir()
1287		classPath := flags.classpath.FormJavaClassPath("")
1288		if classPath != "" {
1289			patchPaths += ":" + classPath
1290		}
1291		javacFlags = append(javacFlags, "--patch-module="+String(j.properties.Patch_module)+"="+patchPaths)
1292	}
1293
1294	// systemModules
1295	flags.systemModules = deps.systemModules
1296
1297	// aidl flags.
1298	flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
1299
1300	if len(javacFlags) > 0 {
1301		// optimization.
1302		ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
1303		flags.javacFlags = "$javacFlags"
1304	}
1305
1306	return flags
1307}
1308
1309func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
1310	j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)
1311
1312	deps := j.collectDeps(ctx)
1313	flags := j.collectBuilderFlags(ctx, deps)
1314
1315	if flags.javaVersion.usesJavaModules() {
1316		j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
1317	}
1318	srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
1319	if hasSrcExt(srcFiles.Strings(), ".proto") {
1320		flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags)
1321	}
1322
1323	kotlinCommonSrcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Common_srcs, nil)
1324	if len(kotlinCommonSrcFiles.FilterOutByExt(".kt")) > 0 {
1325		ctx.PropertyErrorf("common_srcs", "common_srcs must be .kt files")
1326	}
1327
1328	srcFiles = j.genSources(ctx, srcFiles, flags)
1329
1330	srcJars := srcFiles.FilterByExt(".srcjar")
1331	srcJars = append(srcJars, deps.srcJars...)
1332	if aaptSrcJar != nil {
1333		srcJars = append(srcJars, aaptSrcJar)
1334	}
1335
1336	if j.properties.Jarjar_rules != nil {
1337		j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
1338	}
1339
1340	jarName := ctx.ModuleName() + ".jar"
1341
1342	javaSrcFiles := srcFiles.FilterByExt(".java")
1343	var uniqueSrcFiles android.Paths
1344	set := make(map[string]bool)
1345	for _, v := range javaSrcFiles {
1346		if _, found := set[v.String()]; !found {
1347			set[v.String()] = true
1348			uniqueSrcFiles = append(uniqueSrcFiles, v)
1349		}
1350	}
1351
1352	// Collect .java files for AIDEGen
1353	j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...)
1354
1355	var kotlinJars android.Paths
1356
1357	if srcFiles.HasExt(".kt") {
1358		// user defined kotlin flags.
1359		kotlincFlags := j.properties.Kotlincflags
1360		CheckKotlincFlags(ctx, kotlincFlags)
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		if len(kotlincFlags) > 0 {
1370			// optimization.
1371			ctx.Variable(pctx, "kotlincFlags", strings.Join(kotlincFlags, " "))
1372			flags.kotlincFlags += "$kotlincFlags"
1373		}
1374
1375		var kotlinSrcFiles android.Paths
1376		kotlinSrcFiles = append(kotlinSrcFiles, uniqueSrcFiles...)
1377		kotlinSrcFiles = append(kotlinSrcFiles, srcFiles.FilterByExt(".kt")...)
1378
1379		// Collect .kt files for AIDEGen
1380		j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.FilterByExt(".kt").Strings()...)
1381		j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...)
1382
1383		flags.classpath = append(flags.classpath, deps.kotlinStdlib...)
1384		flags.classpath = append(flags.classpath, deps.kotlinAnnotations...)
1385
1386		flags.kotlincClasspath = append(flags.kotlincClasspath, flags.bootClasspath...)
1387		flags.kotlincClasspath = append(flags.kotlincClasspath, flags.classpath...)
1388
1389		if len(flags.processorPath) > 0 {
1390			// Use kapt for annotation processing
1391			kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar")
1392			kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar")
1393			kotlinKapt(ctx, kaptSrcJar, kaptResJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
1394			srcJars = append(srcJars, kaptSrcJar)
1395			kotlinJars = append(kotlinJars, kaptResJar)
1396			// Disable annotation processing in javac, it's already been handled by kapt
1397			flags.processorPath = nil
1398			flags.processors = nil
1399		}
1400
1401		kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
1402		kotlinCompile(ctx, kotlinJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
1403		if ctx.Failed() {
1404			return
1405		}
1406
1407		// Make javac rule depend on the kotlinc rule
1408		flags.classpath = append(flags.classpath, kotlinJar)
1409
1410		kotlinJars = append(kotlinJars, kotlinJar)
1411		// Jar kotlin classes into the final jar after javac
1412		if BoolDefault(j.properties.Static_kotlin_stdlib, true) {
1413			kotlinJars = append(kotlinJars, deps.kotlinStdlib...)
1414		}
1415	}
1416
1417	jars := append(android.Paths(nil), kotlinJars...)
1418
1419	// Store the list of .java files that was passed to javac
1420	j.compiledJavaSrcs = uniqueSrcFiles
1421	j.compiledSrcJars = srcJars
1422
1423	enable_sharding := false
1424	var headerJarFileWithoutJarjar android.Path
1425	if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !deps.disableTurbine {
1426		if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
1427			enable_sharding = true
1428			// Formerly, there was a check here that prevented annotation processors
1429			// from being used when sharding was enabled, as some annotation processors
1430			// do not function correctly in sharded environments. It was removed to
1431			// allow for the use of annotation processors that do function correctly
1432			// with sharding enabled. See: b/77284273.
1433		}
1434		headerJarFileWithoutJarjar, j.headerJarFile =
1435			j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinJars)
1436		if ctx.Failed() {
1437			return
1438		}
1439	}
1440	if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 {
1441		var extraJarDeps android.Paths
1442		if ctx.Config().RunErrorProne() {
1443			// If error-prone is enabled, add an additional rule to compile the java files into
1444			// a separate set of classes (so that they don't overwrite the normal ones and require
1445			// a rebuild when error-prone is turned off).
1446			// TODO(ccross): Once we always compile with javac9 we may be able to conditionally
1447			//    enable error-prone without affecting the output class files.
1448			errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
1449			RunErrorProne(ctx, errorprone, uniqueSrcFiles, srcJars, flags)
1450			extraJarDeps = append(extraJarDeps, errorprone)
1451		}
1452
1453		if enable_sharding {
1454			flags.classpath = append(flags.classpath, headerJarFileWithoutJarjar)
1455			shardSize := int(*(j.properties.Javac_shard_size))
1456			var shardSrcs []android.Paths
1457			if len(uniqueSrcFiles) > 0 {
1458				shardSrcs = android.ShardPaths(uniqueSrcFiles, shardSize)
1459				for idx, shardSrc := range shardSrcs {
1460					classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
1461						nil, flags, extraJarDeps)
1462					jars = append(jars, classes)
1463				}
1464			}
1465			if len(srcJars) > 0 {
1466				classes := j.compileJavaClasses(ctx, jarName, len(shardSrcs),
1467					nil, srcJars, flags, extraJarDeps)
1468				jars = append(jars, classes)
1469			}
1470		} else {
1471			classes := j.compileJavaClasses(ctx, jarName, -1, uniqueSrcFiles, srcJars, flags, extraJarDeps)
1472			jars = append(jars, classes)
1473		}
1474		if ctx.Failed() {
1475			return
1476		}
1477	}
1478
1479	j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles
1480
1481	var includeSrcJar android.WritablePath
1482	if Bool(j.properties.Include_srcs) {
1483		includeSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+".srcjar")
1484		TransformResourcesToJar(ctx, includeSrcJar, j.srcJarArgs, j.srcJarDeps)
1485	}
1486
1487	dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs,
1488		j.properties.Exclude_java_resource_dirs, j.properties.Exclude_java_resources)
1489	fileArgs, fileDeps := ResourceFilesToJarArgs(ctx, j.properties.Java_resources, j.properties.Exclude_java_resources)
1490	extraArgs, extraDeps := resourcePathsToJarArgs(j.extraResources), j.extraResources
1491
1492	var resArgs []string
1493	var resDeps android.Paths
1494
1495	resArgs = append(resArgs, dirArgs...)
1496	resDeps = append(resDeps, dirDeps...)
1497
1498	resArgs = append(resArgs, fileArgs...)
1499	resDeps = append(resDeps, fileDeps...)
1500
1501	resArgs = append(resArgs, extraArgs...)
1502	resDeps = append(resDeps, extraDeps...)
1503
1504	if len(resArgs) > 0 {
1505		resourceJar := android.PathForModuleOut(ctx, "res", jarName)
1506		TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
1507		j.resourceJar = resourceJar
1508		if ctx.Failed() {
1509			return
1510		}
1511	}
1512
1513	var resourceJars android.Paths
1514	if j.resourceJar != nil {
1515		resourceJars = append(resourceJars, j.resourceJar)
1516	}
1517	if Bool(j.properties.Include_srcs) {
1518		resourceJars = append(resourceJars, includeSrcJar)
1519	}
1520	resourceJars = append(resourceJars, deps.staticResourceJars...)
1521
1522	if len(resourceJars) > 1 {
1523		combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
1524		TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{},
1525			false, nil, nil)
1526		j.resourceJar = combinedJar
1527	} else if len(resourceJars) == 1 {
1528		j.resourceJar = resourceJars[0]
1529	}
1530
1531	if len(deps.staticJars) > 0 {
1532		jars = append(jars, deps.staticJars...)
1533	}
1534
1535	manifest := j.overrideManifest
1536	if !manifest.Valid() && j.properties.Manifest != nil {
1537		manifest = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *j.properties.Manifest))
1538	}
1539
1540	services := android.PathsForModuleSrc(ctx, j.properties.Services)
1541	if len(services) > 0 {
1542		servicesJar := android.PathForModuleOut(ctx, "services", jarName)
1543		var zipargs []string
1544		for _, file := range services {
1545			serviceFile := file.String()
1546			zipargs = append(zipargs, "-C", filepath.Dir(serviceFile), "-f", serviceFile)
1547		}
1548		rule := zip
1549		args := map[string]string{
1550			"jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "),
1551		}
1552		if ctx.Config().IsEnvTrue("RBE_ZIP") {
1553			rule = zipRE
1554			args["implicits"] = strings.Join(services.Strings(), ",")
1555		}
1556		ctx.Build(pctx, android.BuildParams{
1557			Rule:      rule,
1558			Output:    servicesJar,
1559			Implicits: services,
1560			Args:      args,
1561		})
1562		jars = append(jars, servicesJar)
1563	}
1564
1565	// Combine the classes built from sources, any manifests, and any static libraries into
1566	// classes.jar. If there is only one input jar this step will be skipped.
1567	var outputFile android.ModuleOutPath
1568
1569	if len(jars) == 1 && !manifest.Valid() {
1570		if moduleOutPath, ok := jars[0].(android.ModuleOutPath); ok {
1571			// Optimization: skip the combine step if there is nothing to do
1572			// TODO(ccross): this leaves any module-info.class files, but those should only come from
1573			// prebuilt dependencies until we support modules in the platform build, so there shouldn't be
1574			// any if len(jars) == 1.
1575			outputFile = moduleOutPath
1576		} else {
1577			combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
1578			ctx.Build(pctx, android.BuildParams{
1579				Rule:   android.Cp,
1580				Input:  jars[0],
1581				Output: combinedJar,
1582			})
1583			outputFile = combinedJar
1584		}
1585	} else {
1586		combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
1587		TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest,
1588			false, nil, nil)
1589		outputFile = combinedJar
1590	}
1591
1592	// jarjar implementation jar if necessary
1593	if j.expandJarjarRules != nil {
1594		// Transform classes.jar into classes-jarjar.jar
1595		jarjarFile := android.PathForModuleOut(ctx, "jarjar", jarName)
1596		TransformJarJar(ctx, jarjarFile, outputFile, j.expandJarjarRules)
1597		outputFile = jarjarFile
1598
1599		// jarjar resource jar if necessary
1600		if j.resourceJar != nil {
1601			resourceJarJarFile := android.PathForModuleOut(ctx, "res-jarjar", jarName)
1602			TransformJarJar(ctx, resourceJarJarFile, j.resourceJar, j.expandJarjarRules)
1603			j.resourceJar = resourceJarJarFile
1604		}
1605
1606		if ctx.Failed() {
1607			return
1608		}
1609	}
1610
1611	// Check package restrictions if necessary.
1612	if len(j.properties.Permitted_packages) > 0 {
1613		// Check packages and copy to package-checked file.
1614		pkgckFile := android.PathForModuleOut(ctx, "package-check.stamp")
1615		CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages)
1616		j.additionalCheckedModules = append(j.additionalCheckedModules, pkgckFile)
1617
1618		if ctx.Failed() {
1619			return
1620		}
1621	}
1622
1623	j.implementationJarFile = outputFile
1624	if j.headerJarFile == nil {
1625		j.headerJarFile = j.implementationJarFile
1626	}
1627
1628	if j.shouldInstrumentInApex(ctx) {
1629		j.properties.Instrument = true
1630	}
1631
1632	if j.shouldInstrument(ctx) {
1633		outputFile = j.instrument(ctx, flags, outputFile, jarName)
1634	}
1635
1636	// merge implementation jar with resources if necessary
1637	implementationAndResourcesJar := outputFile
1638	if j.resourceJar != nil {
1639		jars := android.Paths{j.resourceJar, implementationAndResourcesJar}
1640		combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
1641		TransformJarsToJar(ctx, combinedJar, "for resources", jars, manifest,
1642			false, nil, nil)
1643		implementationAndResourcesJar = combinedJar
1644	}
1645
1646	j.implementationAndResourcesJar = implementationAndResourcesJar
1647
1648	// Enable dex compilation for the APEX variants, unless it is disabled explicitly
1649	if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !j.IsForPlatform() {
1650		if j.deviceProperties.Compile_dex == nil {
1651			j.deviceProperties.Compile_dex = proptools.BoolPtr(true)
1652		}
1653		if j.deviceProperties.Hostdex == nil {
1654			j.deviceProperties.Hostdex = proptools.BoolPtr(true)
1655		}
1656	}
1657
1658	if ctx.Device() && j.hasCode(ctx) &&
1659		(Bool(j.properties.Installable) || Bool(j.deviceProperties.Compile_dex)) {
1660		// Dex compilation
1661		var dexOutputFile android.ModuleOutPath
1662		dexOutputFile = j.compileDex(ctx, flags, outputFile, jarName)
1663		if ctx.Failed() {
1664			return
1665		}
1666
1667		configurationName := j.ConfigurationName()
1668		primary := configurationName == ctx.ModuleName()
1669
1670		// Hidden API CSV generation and dex encoding
1671		dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, configurationName, primary, dexOutputFile, j.implementationJarFile,
1672			proptools.Bool(j.deviceProperties.Uncompress_dex))
1673
1674		// merge dex jar with resources if necessary
1675		if j.resourceJar != nil {
1676			jars := android.Paths{dexOutputFile, j.resourceJar}
1677			combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
1678			TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{},
1679				false, nil, nil)
1680			if *j.deviceProperties.Uncompress_dex {
1681				combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName)
1682				TransformZipAlign(ctx, combinedAlignedJar, combinedJar)
1683				dexOutputFile = combinedAlignedJar
1684			} else {
1685				dexOutputFile = combinedJar
1686			}
1687		}
1688
1689		j.dexJarFile = dexOutputFile
1690
1691		// Dexpreopting
1692		dexOutputFile = j.dexpreopt(ctx, dexOutputFile)
1693
1694		j.maybeStrippedDexJarFile = dexOutputFile
1695
1696		outputFile = dexOutputFile
1697
1698		if ctx.Failed() {
1699			return
1700		}
1701	} else {
1702		outputFile = implementationAndResourcesJar
1703	}
1704
1705	if ctx.Device() {
1706		lintSDKVersionString := func(sdkSpec sdkSpec) string {
1707			if v := sdkSpec.version; v.isNumbered() {
1708				return v.String()
1709			} else {
1710				return ctx.Config().DefaultAppTargetSdk()
1711			}
1712		}
1713
1714		j.linter.name = ctx.ModuleName()
1715		j.linter.srcs = srcFiles
1716		j.linter.srcJars = srcJars
1717		j.linter.classpath = append(append(android.Paths(nil), flags.bootClasspath...), flags.classpath...)
1718		j.linter.classes = j.implementationJarFile
1719		j.linter.minSdkVersion = lintSDKVersionString(j.minSdkVersion())
1720		j.linter.targetSdkVersion = lintSDKVersionString(j.targetSdkVersion())
1721		j.linter.compileSdkVersion = lintSDKVersionString(j.sdkVersion())
1722		j.linter.javaLanguageLevel = flags.javaVersion.String()
1723		j.linter.kotlinLanguageLevel = "1.3"
1724		if j.ApexName() != "" && ctx.Config().UnbundledBuildApps() {
1725			j.linter.buildModuleReportZip = true
1726		}
1727		j.linter.lint(ctx)
1728	}
1729
1730	ctx.CheckbuildFile(outputFile)
1731
1732	// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
1733	j.outputFile = outputFile.WithoutRel()
1734}
1735
1736func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, idx int,
1737	srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.WritablePath {
1738
1739	kzipName := pathtools.ReplaceExtension(jarName, "kzip")
1740	if idx >= 0 {
1741		kzipName = strings.TrimSuffix(jarName, filepath.Ext(jarName)) + strconv.Itoa(idx) + ".kzip"
1742		jarName += strconv.Itoa(idx)
1743	}
1744
1745	classes := android.PathForModuleOut(ctx, "javac", jarName)
1746	TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, flags, extraJarDeps)
1747
1748	if ctx.Config().EmitXrefRules() {
1749		extractionFile := android.PathForModuleOut(ctx, kzipName)
1750		emitXrefRule(ctx, extractionFile, idx, srcFiles, srcJars, flags, extraJarDeps)
1751		j.kytheFiles = append(j.kytheFiles, extractionFile)
1752	}
1753
1754	return classes
1755}
1756
1757// Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user,
1758// since some of these flags may be used internally.
1759func CheckKotlincFlags(ctx android.ModuleContext, flags []string) {
1760	for _, flag := range flags {
1761		flag = strings.TrimSpace(flag)
1762
1763		if !strings.HasPrefix(flag, "-") {
1764			ctx.PropertyErrorf("kotlincflags", "Flag `%s` must start with `-`", flag)
1765		} else if strings.HasPrefix(flag, "-Xintellij-plugin-root") {
1766			ctx.PropertyErrorf("kotlincflags",
1767				"Bad flag: `%s`, only use internal compiler for consistency.", flag)
1768		} else if inList(flag, config.KotlincIllegalFlags) {
1769			ctx.PropertyErrorf("kotlincflags", "Flag `%s` already used by build system", flag)
1770		} else if flag == "-include-runtime" {
1771			ctx.PropertyErrorf("kotlincflags", "Bad flag: `%s`, do not include runtime.", flag)
1772		} else {
1773			args := strings.Split(flag, " ")
1774			if args[0] == "-kotlin-home" {
1775				ctx.PropertyErrorf("kotlincflags",
1776					"Bad flag: `%s`, kotlin home already set to default (path to kotlinc in the repo).", flag)
1777			}
1778		}
1779	}
1780}
1781
1782func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
1783	deps deps, flags javaBuilderFlags, jarName string,
1784	extraJars android.Paths) (headerJar, jarjarHeaderJar android.Path) {
1785
1786	var jars android.Paths
1787	if len(srcFiles) > 0 || len(srcJars) > 0 {
1788		// Compile java sources into turbine.jar.
1789		turbineJar := android.PathForModuleOut(ctx, "turbine", jarName)
1790		TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags)
1791		if ctx.Failed() {
1792			return nil, nil
1793		}
1794		jars = append(jars, turbineJar)
1795	}
1796
1797	jars = append(jars, extraJars...)
1798
1799	// Combine any static header libraries into classes-header.jar. If there is only
1800	// one input jar this step will be skipped.
1801	jars = append(jars, deps.staticHeaderJars...)
1802
1803	// we cannot skip the combine step for now if there is only one jar
1804	// since we have to strip META-INF/TRANSITIVE dir from turbine.jar
1805	combinedJar := android.PathForModuleOut(ctx, "turbine-combined", jarName)
1806	TransformJarsToJar(ctx, combinedJar, "for turbine", jars, android.OptionalPath{},
1807		false, nil, []string{"META-INF/TRANSITIVE"})
1808	headerJar = combinedJar
1809	jarjarHeaderJar = combinedJar
1810
1811	if j.expandJarjarRules != nil {
1812		// Transform classes.jar into classes-jarjar.jar
1813		jarjarFile := android.PathForModuleOut(ctx, "turbine-jarjar", jarName)
1814		TransformJarJar(ctx, jarjarFile, headerJar, j.expandJarjarRules)
1815		jarjarHeaderJar = jarjarFile
1816		if ctx.Failed() {
1817			return nil, nil
1818		}
1819	}
1820
1821	return headerJar, jarjarHeaderJar
1822}
1823
1824func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
1825	classesJar android.Path, jarName string) android.ModuleOutPath {
1826
1827	specs := j.jacocoModuleToZipCommand(ctx)
1828
1829	jacocoReportClassesFile := android.PathForModuleOut(ctx, "jacoco-report-classes", jarName)
1830	instrumentedJar := android.PathForModuleOut(ctx, "jacoco", jarName)
1831
1832	jacocoInstrumentJar(ctx, instrumentedJar, jacocoReportClassesFile, classesJar, specs)
1833
1834	j.jacocoReportClassesFile = jacocoReportClassesFile
1835
1836	return instrumentedJar
1837}
1838
1839var _ Dependency = (*Module)(nil)
1840
1841func (j *Module) HeaderJars() android.Paths {
1842	if j.headerJarFile == nil {
1843		return nil
1844	}
1845	return android.Paths{j.headerJarFile}
1846}
1847
1848func (j *Module) ImplementationJars() android.Paths {
1849	if j.implementationJarFile == nil {
1850		return nil
1851	}
1852	return android.Paths{j.implementationJarFile}
1853}
1854
1855func (j *Module) DexJarBuildPath() android.Path {
1856	return j.dexJarFile
1857}
1858
1859func (j *Module) DexJarInstallPath() android.Path {
1860	return j.installFile
1861}
1862
1863func (j *Module) ResourceJars() android.Paths {
1864	if j.resourceJar == nil {
1865		return nil
1866	}
1867	return android.Paths{j.resourceJar}
1868}
1869
1870func (j *Module) ImplementationAndResourcesJars() android.Paths {
1871	if j.implementationAndResourcesJar == nil {
1872		return nil
1873	}
1874	return android.Paths{j.implementationAndResourcesJar}
1875}
1876
1877func (j *Module) AidlIncludeDirs() android.Paths {
1878	// exportAidlIncludeDirs is type android.Paths already
1879	return j.exportAidlIncludeDirs
1880}
1881
1882func (j *Module) ExportedSdkLibs() []string {
1883	// exportedSdkLibs is type []string
1884	return j.exportedSdkLibs
1885}
1886
1887func (j *Module) ExportedPlugins() (android.Paths, []string) {
1888	return j.exportedPluginJars, j.exportedPluginClasses
1889}
1890
1891func (j *Module) SrcJarArgs() ([]string, android.Paths) {
1892	return j.srcJarArgs, j.srcJarDeps
1893}
1894
1895var _ logtagsProducer = (*Module)(nil)
1896
1897func (j *Module) logtags() android.Paths {
1898	return j.logtagsSrcs
1899}
1900
1901// Collect information for opening IDE project files in java/jdeps.go.
1902func (j *Module) IDEInfo(dpInfo *android.IdeInfo) {
1903	dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...)
1904	dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...)
1905	dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...)
1906	dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...)
1907	if j.expandJarjarRules != nil {
1908		dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
1909	}
1910	dpInfo.Paths = append(dpInfo.Paths, j.modulePaths...)
1911}
1912
1913func (j *Module) CompilerDeps() []string {
1914	jdeps := []string{}
1915	jdeps = append(jdeps, j.properties.Libs...)
1916	jdeps = append(jdeps, j.properties.Static_libs...)
1917	return jdeps
1918}
1919
1920func (j *Module) hasCode(ctx android.ModuleContext) bool {
1921	srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
1922	return len(srcFiles) > 0 || len(ctx.GetDirectDepsWithTag(staticLibTag)) > 0
1923}
1924
1925func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1926	return j.depIsInSameApex(ctx, dep)
1927}
1928
1929func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
1930	sdkSpec := j.minSdkVersion()
1931	if !sdkSpec.specified() {
1932		return fmt.Errorf("min_sdk_version is not specified")
1933	}
1934	if sdkSpec.kind == sdkCore {
1935		return nil
1936	}
1937	ver, err := sdkSpec.effectiveVersion(ctx)
1938	if err != nil {
1939		return err
1940	}
1941	if int(ver) > sdkVersion {
1942		return fmt.Errorf("newer SDK(%v)", ver)
1943	}
1944	return nil
1945}
1946
1947func (j *Module) Stem() string {
1948	return proptools.StringDefault(j.deviceProperties.Stem, j.Name())
1949}
1950
1951func (j *Module) ConfigurationName() string {
1952	return proptools.StringDefault(j.deviceProperties.ConfigurationName, j.BaseModuleName())
1953}
1954
1955func (j *Module) JacocoReportClassesFile() android.Path {
1956	return j.jacocoReportClassesFile
1957}
1958
1959func (j *Module) IsInstallable() bool {
1960	return Bool(j.properties.Installable)
1961}
1962
1963//
1964// Java libraries (.jar file)
1965//
1966
1967type Library struct {
1968	Module
1969
1970	InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths)
1971}
1972
1973// Provides access to the list of permitted packages from updatable boot jars.
1974type PermittedPackagesForUpdatableBootJars interface {
1975	PermittedPackagesForUpdatableBootJars() []string
1976}
1977
1978var _ PermittedPackagesForUpdatableBootJars = (*Library)(nil)
1979
1980func (j *Library) PermittedPackagesForUpdatableBootJars() []string {
1981	return j.properties.Permitted_packages
1982}
1983
1984func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool {
1985	// Store uncompressed (and aligned) any dex files from jars in APEXes.
1986	if am, ok := ctx.Module().(android.ApexModule); ok && !am.IsForPlatform() {
1987		return true
1988	}
1989
1990	// Store uncompressed (and do not strip) dex files from boot class path jars.
1991	if inList(ctx.ModuleName(), ctx.Config().BootJars()) {
1992		return true
1993	}
1994
1995	// Store uncompressed dex files that are preopted on /system.
1996	if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, dexpreopter.installPath)) {
1997		return true
1998	}
1999	if ctx.Config().UncompressPrivAppDex() &&
2000		inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()) {
2001		return true
2002	}
2003
2004	return false
2005}
2006
2007func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2008	j.checkSdkVersions(ctx)
2009	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
2010	j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
2011	if j.deviceProperties.Uncompress_dex == nil {
2012		// If the value was not force-set by the user, use reasonable default based on the module.
2013		j.deviceProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
2014	}
2015	j.dexpreopter.uncompressedDex = *j.deviceProperties.Uncompress_dex
2016	j.compile(ctx, nil)
2017
2018	// Collect the module directory for IDE info in java/jdeps.go.
2019	j.modulePaths = append(j.modulePaths, ctx.ModuleDir())
2020
2021	exclusivelyForApex := android.InAnyApex(ctx.ModuleName()) && !j.IsForPlatform()
2022	if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex {
2023		var extraInstallDeps android.Paths
2024		if j.InstallMixin != nil {
2025			extraInstallDeps = j.InstallMixin(ctx, j.outputFile)
2026		}
2027		j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
2028			j.Stem()+".jar", j.outputFile, extraInstallDeps...)
2029	}
2030
2031	j.distFiles = j.GenerateTaggedDistFiles(ctx)
2032}
2033
2034func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
2035	j.deps(ctx)
2036}
2037
2038const (
2039	aidlIncludeDir   = "aidl"
2040	javaDir          = "java"
2041	jarFileSuffix    = ".jar"
2042	testConfigSuffix = "-AndroidTest.xml"
2043)
2044
2045// path to the jar file of a java library. Relative to <sdk_root>/<api_dir>
2046func sdkSnapshotFilePathForJar(osPrefix, name string) string {
2047	return sdkSnapshotFilePathForMember(osPrefix, name, jarFileSuffix)
2048}
2049
2050func sdkSnapshotFilePathForMember(osPrefix, name string, suffix string) string {
2051	return filepath.Join(javaDir, osPrefix, name+suffix)
2052}
2053
2054type librarySdkMemberType struct {
2055	android.SdkMemberTypeBase
2056
2057	// Function to retrieve the appropriate output jar (implementation or header) from
2058	// the library.
2059	jarToExportGetter func(j *Library) android.Path
2060}
2061
2062func (mt *librarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
2063	mctx.AddVariationDependencies(nil, dependencyTag, names...)
2064}
2065
2066func (mt *librarySdkMemberType) IsInstance(module android.Module) bool {
2067	_, ok := module.(*Library)
2068	return ok
2069}
2070
2071func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
2072	return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_import")
2073}
2074
2075func (mt *librarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
2076	return &librarySdkMemberProperties{}
2077}
2078
2079type librarySdkMemberProperties struct {
2080	android.SdkMemberPropertiesBase
2081
2082	JarToExport     android.Path `android:"arch_variant"`
2083	AidlIncludeDirs android.Paths
2084}
2085
2086func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
2087	j := variant.(*Library)
2088
2089	p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(j)
2090	p.AidlIncludeDirs = j.AidlIncludeDirs()
2091}
2092
2093func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
2094	builder := ctx.SnapshotBuilder()
2095
2096	exportedJar := p.JarToExport
2097	if exportedJar != nil {
2098		snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(p.OsPrefix(), ctx.Name())
2099		builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath)
2100
2101		propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
2102	}
2103
2104	aidlIncludeDirs := p.AidlIncludeDirs
2105	if len(aidlIncludeDirs) != 0 {
2106		sdkModuleContext := ctx.SdkModuleContext()
2107		for _, dir := range aidlIncludeDirs {
2108			// TODO(jiyong): copy parcelable declarations only
2109			aidlFiles, _ := sdkModuleContext.GlobWithDeps(dir.String()+"/**/*.aidl", nil)
2110			for _, file := range aidlFiles {
2111				builder.CopyToSnapshot(android.PathForSource(sdkModuleContext, file), filepath.Join(aidlIncludeDir, file))
2112			}
2113		}
2114
2115		// TODO(b/151933053) - add aidl include dirs property
2116	}
2117}
2118
2119var javaHeaderLibsSdkMemberType android.SdkMemberType = &librarySdkMemberType{
2120	android.SdkMemberTypeBase{
2121		PropertyName: "java_header_libs",
2122		SupportsSdk:  true,
2123	},
2124	func(j *Library) android.Path {
2125		headerJars := j.HeaderJars()
2126		if len(headerJars) != 1 {
2127			panic(fmt.Errorf("there must be only one header jar from %q", j.Name()))
2128		}
2129
2130		return headerJars[0]
2131	},
2132}
2133
2134// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well.
2135//
2136// By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were
2137// compiled against the device bootclasspath.  This jar is not suitable for installing on a device, but can be used
2138// as a `static_libs` dependency of another module.
2139//
2140// Specifying `installable: true` will product a `.jar` file containing `classes.dex` files, suitable for installing on
2141// a device.
2142//
2143// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
2144// compiled against the host bootclasspath.
2145func LibraryFactory() android.Module {
2146	module := &Library{}
2147
2148	module.addHostAndDeviceProperties()
2149
2150	module.initModuleAndImport(&module.ModuleBase)
2151
2152	android.InitApexModule(module)
2153	android.InitSdkAwareModule(module)
2154	InitJavaModule(module, android.HostAndDeviceSupported)
2155	return module
2156}
2157
2158// java_library_static is an obsolete alias for java_library.
2159func LibraryStaticFactory() android.Module {
2160	return LibraryFactory()
2161}
2162
2163// java_library_host builds and links sources into a `.jar` file for the host.
2164//
2165// A java_library_host has a single variant that produces a `.jar` file containing `.class` files that were
2166// compiled against the host bootclasspath.
2167func LibraryHostFactory() android.Module {
2168	module := &Library{}
2169
2170	module.addHostProperties()
2171
2172	module.Module.properties.Installable = proptools.BoolPtr(true)
2173
2174	android.InitApexModule(module)
2175	InitJavaModule(module, android.HostSupported)
2176	return module
2177}
2178
2179//
2180// Java Tests
2181//
2182
2183type testProperties struct {
2184	// list of compatibility suites (for example "cts", "vts") that the module should be
2185	// installed into.
2186	Test_suites []string `android:"arch_variant"`
2187
2188	// the name of the test configuration (for example "AndroidTest.xml") that should be
2189	// installed with the module.
2190	Test_config *string `android:"path,arch_variant"`
2191
2192	// the name of the test configuration template (for example "AndroidTestTemplate.xml") that
2193	// should be installed with the module.
2194	Test_config_template *string `android:"path,arch_variant"`
2195
2196	// list of files or filegroup modules that provide data that should be installed alongside
2197	// the test
2198	Data []string `android:"path"`
2199
2200	// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
2201	// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
2202	// explicitly.
2203	Auto_gen_config *bool
2204
2205	// Add parameterized mainline modules to auto generated test config. The options will be
2206	// handled by TradeFed to do downloading and installing the specified modules on the device.
2207	Test_mainline_modules []string
2208}
2209
2210type hostTestProperties struct {
2211	// list of native binary modules that should be installed alongside the test
2212	Data_native_bins []string `android:"arch_variant"`
2213}
2214
2215type testHelperLibraryProperties struct {
2216	// list of compatibility suites (for example "cts", "vts") that the module should be
2217	// installed into.
2218	Test_suites []string `android:"arch_variant"`
2219}
2220
2221type prebuiltTestProperties struct {
2222	// list of compatibility suites (for example "cts", "vts") that the module should be
2223	// installed into.
2224	Test_suites []string `android:"arch_variant"`
2225
2226	// the name of the test configuration (for example "AndroidTest.xml") that should be
2227	// installed with the module.
2228	Test_config *string `android:"path,arch_variant"`
2229}
2230
2231type Test struct {
2232	Library
2233
2234	testProperties testProperties
2235
2236	testConfig android.Path
2237	data       android.Paths
2238}
2239
2240type TestHost struct {
2241	Test
2242
2243	testHostProperties hostTestProperties
2244}
2245
2246type TestHelperLibrary struct {
2247	Library
2248
2249	testHelperLibraryProperties testHelperLibraryProperties
2250}
2251
2252type JavaTestImport struct {
2253	Import
2254
2255	prebuiltTestProperties prebuiltTestProperties
2256
2257	testConfig android.Path
2258}
2259
2260func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) {
2261	if len(j.testHostProperties.Data_native_bins) > 0 {
2262		for _, target := range ctx.MultiTargets() {
2263			ctx.AddVariationDependencies(target.Variations(), dataNativeBinsTag, j.testHostProperties.Data_native_bins...)
2264		}
2265	}
2266
2267	j.deps(ctx)
2268}
2269
2270func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2271	j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template,
2272		j.testProperties.Test_suites, j.testProperties.Auto_gen_config)
2273
2274	j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
2275
2276	ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) {
2277		j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
2278	})
2279
2280	j.Library.GenerateAndroidBuildActions(ctx)
2281}
2282
2283func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2284	j.Library.GenerateAndroidBuildActions(ctx)
2285}
2286
2287func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2288	j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.prebuiltTestProperties.Test_config, nil,
2289		j.prebuiltTestProperties.Test_suites, nil)
2290
2291	j.Import.GenerateAndroidBuildActions(ctx)
2292}
2293
2294type testSdkMemberType struct {
2295	android.SdkMemberTypeBase
2296}
2297
2298func (mt *testSdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
2299	mctx.AddVariationDependencies(nil, dependencyTag, names...)
2300}
2301
2302func (mt *testSdkMemberType) IsInstance(module android.Module) bool {
2303	_, ok := module.(*Test)
2304	return ok
2305}
2306
2307func (mt *testSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
2308	return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_test_import")
2309}
2310
2311func (mt *testSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
2312	return &testSdkMemberProperties{}
2313}
2314
2315type testSdkMemberProperties struct {
2316	android.SdkMemberPropertiesBase
2317
2318	JarToExport android.Path
2319	TestConfig  android.Path
2320}
2321
2322func (p *testSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
2323	test := variant.(*Test)
2324
2325	implementationJars := test.ImplementationJars()
2326	if len(implementationJars) != 1 {
2327		panic(fmt.Errorf("there must be only one implementation jar from %q", test.Name()))
2328	}
2329
2330	p.JarToExport = implementationJars[0]
2331	p.TestConfig = test.testConfig
2332}
2333
2334func (p *testSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
2335	builder := ctx.SnapshotBuilder()
2336
2337	exportedJar := p.JarToExport
2338	if exportedJar != nil {
2339		snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(p.OsPrefix(), ctx.Name())
2340		builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath)
2341
2342		propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
2343	}
2344
2345	testConfig := p.TestConfig
2346	if testConfig != nil {
2347		snapshotRelativeTestConfigPath := sdkSnapshotFilePathForMember(p.OsPrefix(), ctx.Name(), testConfigSuffix)
2348		builder.CopyToSnapshot(testConfig, snapshotRelativeTestConfigPath)
2349		propertySet.AddProperty("test_config", snapshotRelativeTestConfigPath)
2350	}
2351}
2352
2353// java_test builds a and links sources into a `.jar` file for the device, and possibly for the host as well, and
2354// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
2355//
2356// By default, a java_test has a single variant that produces a `.jar` file containing `classes.dex` files that were
2357// compiled against the device bootclasspath.
2358//
2359// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
2360// compiled against the host bootclasspath.
2361func TestFactory() android.Module {
2362	module := &Test{}
2363
2364	module.addHostAndDeviceProperties()
2365	module.AddProperties(&module.testProperties)
2366
2367	module.Module.properties.Installable = proptools.BoolPtr(true)
2368	module.Module.dexpreopter.isTest = true
2369	module.Module.linter.test = true
2370
2371	InitJavaModule(module, android.HostAndDeviceSupported)
2372	return module
2373}
2374
2375// java_test_helper_library creates a java library and makes sure that it is added to the appropriate test suite.
2376func TestHelperLibraryFactory() android.Module {
2377	module := &TestHelperLibrary{}
2378
2379	module.addHostAndDeviceProperties()
2380	module.AddProperties(&module.testHelperLibraryProperties)
2381
2382	module.Module.properties.Installable = proptools.BoolPtr(true)
2383	module.Module.dexpreopter.isTest = true
2384	module.Module.linter.test = true
2385
2386	InitJavaModule(module, android.HostAndDeviceSupported)
2387	return module
2388}
2389
2390// java_test_import imports one or more `.jar` files into the build graph as if they were built by a java_test module
2391// and makes sure that it is added to the appropriate test suite.
2392//
2393// By default, a java_test_import has a single variant that expects a `.jar` file containing `.class` files that were
2394// compiled against an Android classpath.
2395//
2396// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
2397// for host modules.
2398func JavaTestImportFactory() android.Module {
2399	module := &JavaTestImport{}
2400
2401	module.AddProperties(
2402		&module.Import.properties,
2403		&module.prebuiltTestProperties)
2404
2405	module.Import.properties.Installable = proptools.BoolPtr(true)
2406
2407	android.InitPrebuiltModule(module, &module.properties.Jars)
2408	android.InitApexModule(module)
2409	android.InitSdkAwareModule(module)
2410	InitJavaModule(module, android.HostAndDeviceSupported)
2411	return module
2412}
2413
2414// java_test_host builds a and links sources into a `.jar` file for the host, and creates an `AndroidTest.xml` file to
2415// allow running the test with `atest` or a `TEST_MAPPING` file.
2416//
2417// A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were
2418// compiled against the host bootclasspath.
2419func TestHostFactory() android.Module {
2420	module := &TestHost{}
2421
2422	module.addHostProperties()
2423	module.AddProperties(&module.testProperties)
2424	module.AddProperties(&module.testHostProperties)
2425
2426	module.Module.properties.Installable = proptools.BoolPtr(true)
2427
2428	InitJavaModuleMultiTargets(module, android.HostSupported)
2429	return module
2430}
2431
2432//
2433// Java Binaries (.jar file plus wrapper script)
2434//
2435
2436type binaryProperties struct {
2437	// installable script to execute the resulting jar
2438	Wrapper *string `android:"path"`
2439
2440	// Name of the class containing main to be inserted into the manifest as Main-Class.
2441	Main_class *string
2442}
2443
2444type Binary struct {
2445	Library
2446
2447	binaryProperties binaryProperties
2448
2449	isWrapperVariant bool
2450
2451	wrapperFile android.Path
2452	binaryFile  android.InstallPath
2453}
2454
2455func (j *Binary) HostToolPath() android.OptionalPath {
2456	return android.OptionalPathForPath(j.binaryFile)
2457}
2458
2459func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2460	if ctx.Arch().ArchType == android.Common {
2461		// Compile the jar
2462		if j.binaryProperties.Main_class != nil {
2463			if j.properties.Manifest != nil {
2464				ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set")
2465			}
2466			manifestFile := android.PathForModuleOut(ctx, "manifest.txt")
2467			GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class))
2468			j.overrideManifest = android.OptionalPathForPath(manifestFile)
2469		}
2470
2471		j.Library.GenerateAndroidBuildActions(ctx)
2472	} else {
2473		// Handle the binary wrapper
2474		j.isWrapperVariant = true
2475
2476		if j.binaryProperties.Wrapper != nil {
2477			j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper)
2478		} else {
2479			j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh")
2480		}
2481
2482		// Depend on the installed jar so that the wrapper doesn't get executed by
2483		// another build rule before the jar has been installed.
2484		jarFile := ctx.PrimaryModule().(*Binary).installFile
2485
2486		j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"),
2487			ctx.ModuleName(), j.wrapperFile, jarFile)
2488	}
2489}
2490
2491func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
2492	if ctx.Arch().ArchType == android.Common {
2493		j.deps(ctx)
2494	}
2495}
2496
2497// java_binary builds a `.jar` file and a shell script that executes it for the device, and possibly for the host
2498// as well.
2499//
2500// By default, a java_binary has a single variant that produces a `.jar` file containing `classes.dex` files that were
2501// compiled against the device bootclasspath.
2502//
2503// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
2504// compiled against the host bootclasspath.
2505func BinaryFactory() android.Module {
2506	module := &Binary{}
2507
2508	module.addHostAndDeviceProperties()
2509	module.AddProperties(&module.binaryProperties)
2510
2511	module.Module.properties.Installable = proptools.BoolPtr(true)
2512
2513	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst)
2514	android.InitDefaultableModule(module)
2515	return module
2516}
2517
2518// java_binary_host builds a `.jar` file and a shell script that executes it for the host.
2519//
2520// A java_binary_host has a single variant that produces a `.jar` file containing `.class` files that were
2521// compiled against the host bootclasspath.
2522func BinaryHostFactory() android.Module {
2523	module := &Binary{}
2524
2525	module.addHostProperties()
2526	module.AddProperties(&module.binaryProperties)
2527
2528	module.Module.properties.Installable = proptools.BoolPtr(true)
2529
2530	android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst)
2531	android.InitDefaultableModule(module)
2532	return module
2533}
2534
2535//
2536// Java prebuilts
2537//
2538
2539type ImportProperties struct {
2540	Jars []string `android:"path,arch_variant"`
2541
2542	Sdk_version *string
2543
2544	Installable *bool
2545
2546	// List of shared java libs that this module has dependencies to
2547	Libs []string
2548
2549	// List of files to remove from the jar file(s)
2550	Exclude_files []string
2551
2552	// List of directories to remove from the jar file(s)
2553	Exclude_dirs []string
2554
2555	// if set to true, run Jetifier against .jar file. Defaults to false.
2556	Jetifier *bool
2557
2558	// set the name of the output
2559	Stem *string
2560
2561	Aidl struct {
2562		// directories that should be added as include directories for any aidl sources of modules
2563		// that depend on this module, as well as to aidl for this module.
2564		Export_include_dirs []string
2565	}
2566}
2567
2568type Import struct {
2569	android.ModuleBase
2570	android.DefaultableModuleBase
2571	android.ApexModuleBase
2572	prebuilt android.Prebuilt
2573	android.SdkBase
2574
2575	// Functionality common to Module and Import.
2576	embeddableInModuleAndImport
2577
2578	properties ImportProperties
2579
2580	combinedClasspathFile android.Path
2581	exportedSdkLibs       []string
2582	exportAidlIncludeDirs android.Paths
2583}
2584
2585func (j *Import) sdkVersion() sdkSpec {
2586	return sdkSpecFrom(String(j.properties.Sdk_version))
2587}
2588
2589func (j *Import) minSdkVersion() sdkSpec {
2590	return j.sdkVersion()
2591}
2592
2593func (j *Import) MinSdkVersion() string {
2594	return j.minSdkVersion().version.String()
2595}
2596
2597func (j *Import) Prebuilt() *android.Prebuilt {
2598	return &j.prebuilt
2599}
2600
2601func (j *Import) PrebuiltSrcs() []string {
2602	return j.properties.Jars
2603}
2604
2605func (j *Import) Name() string {
2606	return j.prebuilt.Name(j.ModuleBase.Name())
2607}
2608
2609func (j *Import) Stem() string {
2610	return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
2611}
2612
2613func (a *Import) JacocoReportClassesFile() android.Path {
2614	return nil
2615}
2616
2617func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
2618	ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
2619}
2620
2621func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2622	jars := android.PathsForModuleSrc(ctx, j.properties.Jars)
2623
2624	jarName := j.Stem() + ".jar"
2625	outputFile := android.PathForModuleOut(ctx, "combined", jarName)
2626	TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{},
2627		false, j.properties.Exclude_files, j.properties.Exclude_dirs)
2628	if Bool(j.properties.Jetifier) {
2629		inputFile := outputFile
2630		outputFile = android.PathForModuleOut(ctx, "jetifier", jarName)
2631		TransformJetifier(ctx, outputFile, inputFile)
2632	}
2633	j.combinedClasspathFile = outputFile
2634
2635	// If this is a component library (impl, stubs, etc.) for a java_sdk_library then
2636	// add the name of that java_sdk_library to the exported sdk libs to make sure
2637	// that, if necessary, a <uses-library> element for that java_sdk_library is
2638	// added to the Android manifest.
2639	j.exportedSdkLibs = append(j.exportedSdkLibs, j.OptionalImplicitSdkLibrary()...)
2640
2641	ctx.VisitDirectDeps(func(module android.Module) {
2642		otherName := ctx.OtherModuleName(module)
2643		tag := ctx.OtherModuleDependencyTag(module)
2644
2645		switch dep := module.(type) {
2646		case Dependency:
2647			switch tag {
2648			case libTag, staticLibTag:
2649				// sdk lib names from dependencies are re-exported
2650				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
2651			}
2652		case SdkLibraryDependency:
2653			switch tag {
2654			case libTag:
2655				// names of sdk libs that are directly depended are exported
2656				j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
2657			}
2658		}
2659	})
2660
2661	j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)
2662	if Bool(j.properties.Installable) {
2663		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
2664			jarName, outputFile)
2665	}
2666
2667	j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs)
2668}
2669
2670var _ Dependency = (*Import)(nil)
2671
2672func (j *Import) HeaderJars() android.Paths {
2673	if j.combinedClasspathFile == nil {
2674		return nil
2675	}
2676	return android.Paths{j.combinedClasspathFile}
2677}
2678
2679func (j *Import) ImplementationJars() android.Paths {
2680	if j.combinedClasspathFile == nil {
2681		return nil
2682	}
2683	return android.Paths{j.combinedClasspathFile}
2684}
2685
2686func (j *Import) ResourceJars() android.Paths {
2687	return nil
2688}
2689
2690func (j *Import) ImplementationAndResourcesJars() android.Paths {
2691	if j.combinedClasspathFile == nil {
2692		return nil
2693	}
2694	return android.Paths{j.combinedClasspathFile}
2695}
2696
2697func (j *Import) DexJarBuildPath() android.Path {
2698	return nil
2699}
2700
2701func (j *Import) DexJarInstallPath() android.Path {
2702	return nil
2703}
2704
2705func (j *Import) AidlIncludeDirs() android.Paths {
2706	return j.exportAidlIncludeDirs
2707}
2708
2709func (j *Import) ExportedSdkLibs() []string {
2710	return j.exportedSdkLibs
2711}
2712
2713func (j *Import) ExportedPlugins() (android.Paths, []string) {
2714	return nil, nil
2715}
2716
2717func (j *Import) SrcJarArgs() ([]string, android.Paths) {
2718	return nil, nil
2719}
2720
2721func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
2722	return j.depIsInSameApex(ctx, dep)
2723}
2724
2725func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
2726	// Do not check for prebuilts against the min_sdk_version of enclosing APEX
2727	return nil
2728}
2729
2730// Add compile time check for interface implementation
2731var _ android.IDEInfo = (*Import)(nil)
2732var _ android.IDECustomizedModuleName = (*Import)(nil)
2733
2734// Collect information for opening IDE project files in java/jdeps.go.
2735const (
2736	removedPrefix = "prebuilt_"
2737)
2738
2739func (j *Import) IDEInfo(dpInfo *android.IdeInfo) {
2740	dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...)
2741}
2742
2743func (j *Import) IDECustomizedModuleName() string {
2744	// TODO(b/113562217): Extract the base module name from the Import name, often the Import name
2745	// has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better
2746	// solution to get the Import name.
2747	name := j.Name()
2748	if strings.HasPrefix(name, removedPrefix) {
2749		name = strings.TrimPrefix(name, removedPrefix)
2750	}
2751	return name
2752}
2753
2754var _ android.PrebuiltInterface = (*Import)(nil)
2755
2756// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module.
2757//
2758// By default, a java_import has a single variant that expects a `.jar` file containing `.class` files that were
2759// compiled against an Android classpath.
2760//
2761// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
2762// for host modules.
2763func ImportFactory() android.Module {
2764	module := &Import{}
2765
2766	module.AddProperties(&module.properties)
2767
2768	module.initModuleAndImport(&module.ModuleBase)
2769
2770	android.InitPrebuiltModule(module, &module.properties.Jars)
2771	android.InitApexModule(module)
2772	android.InitSdkAwareModule(module)
2773	InitJavaModule(module, android.HostAndDeviceSupported)
2774	return module
2775}
2776
2777// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library_host
2778// module.
2779//
2780// A java_import_host has a single variant that expects a `.jar` file containing `.class` files that were
2781// compiled against a host bootclasspath.
2782func ImportFactoryHost() android.Module {
2783	module := &Import{}
2784
2785	module.AddProperties(&module.properties)
2786
2787	android.InitPrebuiltModule(module, &module.properties.Jars)
2788	android.InitApexModule(module)
2789	InitJavaModule(module, android.HostSupported)
2790	return module
2791}
2792
2793// dex_import module
2794
2795type DexImportProperties struct {
2796	Jars []string `android:"path"`
2797
2798	// set the name of the output
2799	Stem *string
2800}
2801
2802type DexImport struct {
2803	android.ModuleBase
2804	android.DefaultableModuleBase
2805	android.ApexModuleBase
2806	prebuilt android.Prebuilt
2807
2808	properties DexImportProperties
2809
2810	dexJarFile              android.Path
2811	maybeStrippedDexJarFile android.Path
2812
2813	dexpreopter
2814}
2815
2816func (j *DexImport) Prebuilt() *android.Prebuilt {
2817	return &j.prebuilt
2818}
2819
2820func (j *DexImport) PrebuiltSrcs() []string {
2821	return j.properties.Jars
2822}
2823
2824func (j *DexImport) Name() string {
2825	return j.prebuilt.Name(j.ModuleBase.Name())
2826}
2827
2828func (j *DexImport) Stem() string {
2829	return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
2830}
2831
2832func (a *DexImport) JacocoReportClassesFile() android.Path {
2833	return nil
2834}
2835
2836func (a *DexImport) LintDepSets() LintDepSets {
2837	return LintDepSets{}
2838}
2839
2840func (j *DexImport) IsInstallable() bool {
2841	return true
2842}
2843
2844func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2845	if len(j.properties.Jars) != 1 {
2846		ctx.PropertyErrorf("jars", "exactly one jar must be provided")
2847	}
2848
2849	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
2850	j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
2851
2852	inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars")
2853	dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar")
2854
2855	if j.dexpreopter.uncompressedDex {
2856		rule := android.NewRuleBuilder()
2857
2858		temporary := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar.unaligned")
2859		rule.Temporary(temporary)
2860
2861		// use zip2zip to uncompress classes*.dex files
2862		rule.Command().
2863			BuiltTool(ctx, "zip2zip").
2864			FlagWithInput("-i ", inputJar).
2865			FlagWithOutput("-o ", temporary).
2866			FlagWithArg("-0 ", "'classes*.dex'")
2867
2868		// use zipalign to align uncompressed classes*.dex files
2869		rule.Command().
2870			BuiltTool(ctx, "zipalign").
2871			Flag("-f").
2872			Text("4").
2873			Input(temporary).
2874			Output(dexOutputFile)
2875
2876		rule.DeleteTemporaryFiles()
2877
2878		rule.Build(pctx, ctx, "uncompress_dex", "uncompress dex")
2879	} else {
2880		ctx.Build(pctx, android.BuildParams{
2881			Rule:   android.Cp,
2882			Input:  inputJar,
2883			Output: dexOutputFile,
2884		})
2885	}
2886
2887	j.dexJarFile = dexOutputFile
2888
2889	dexOutputFile = j.dexpreopt(ctx, dexOutputFile)
2890
2891	j.maybeStrippedDexJarFile = dexOutputFile
2892
2893	if j.IsForPlatform() {
2894		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
2895			j.Stem()+".jar", dexOutputFile)
2896	}
2897}
2898
2899func (j *DexImport) DexJarBuildPath() android.Path {
2900	return j.dexJarFile
2901}
2902
2903func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
2904	// we don't check prebuilt modules for sdk_version
2905	return nil
2906}
2907
2908// dex_import imports a `.jar` file containing classes.dex files.
2909//
2910// A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed
2911// to the device.
2912func DexImportFactory() android.Module {
2913	module := &DexImport{}
2914
2915	module.AddProperties(&module.properties)
2916
2917	android.InitPrebuiltModule(module, &module.properties.Jars)
2918	android.InitApexModule(module)
2919	InitJavaModule(module, android.DeviceSupported)
2920	return module
2921}
2922
2923//
2924// Defaults
2925//
2926type Defaults struct {
2927	android.ModuleBase
2928	android.DefaultsModuleBase
2929	android.ApexModuleBase
2930}
2931
2932// java_defaults provides a set of properties that can be inherited by other java or android modules.
2933//
2934// A module can use the properties from a java_defaults module using `defaults: ["defaults_module_name"]`.  Each
2935// property in the defaults module that exists in the depending module will be prepended to the depending module's
2936// value for that property.
2937//
2938// Example:
2939//
2940//     java_defaults {
2941//         name: "example_defaults",
2942//         srcs: ["common/**/*.java"],
2943//         javacflags: ["-Xlint:all"],
2944//         aaptflags: ["--auto-add-overlay"],
2945//     }
2946//
2947//     java_library {
2948//         name: "example",
2949//         defaults: ["example_defaults"],
2950//         srcs: ["example/**/*.java"],
2951//     }
2952//
2953// is functionally identical to:
2954//
2955//     java_library {
2956//         name: "example",
2957//         srcs: [
2958//             "common/**/*.java",
2959//             "example/**/*.java",
2960//         ],
2961//         javacflags: ["-Xlint:all"],
2962//     }
2963func defaultsFactory() android.Module {
2964	return DefaultsFactory()
2965}
2966
2967func DefaultsFactory() android.Module {
2968	module := &Defaults{}
2969
2970	module.AddProperties(
2971		&CompilerProperties{},
2972		&CompilerDeviceProperties{},
2973		&DexpreoptProperties{},
2974		&android.ProtoProperties{},
2975		&aaptProperties{},
2976		&androidLibraryProperties{},
2977		&appProperties{},
2978		&appTestProperties{},
2979		&overridableAppProperties{},
2980		&testProperties{},
2981		&ImportProperties{},
2982		&AARImportProperties{},
2983		&sdkLibraryProperties{},
2984		&commonToSdkLibraryAndImportProperties{},
2985		&DexImportProperties{},
2986		&android.ApexProperties{},
2987		&RuntimeResourceOverlayProperties{},
2988		&LintProperties{},
2989	)
2990
2991	android.InitDefaultsModule(module)
2992	return module
2993}
2994
2995func kytheExtractJavaFactory() android.Singleton {
2996	return &kytheExtractJavaSingleton{}
2997}
2998
2999type kytheExtractJavaSingleton struct {
3000}
3001
3002func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) {
3003	var xrefTargets android.Paths
3004	ctx.VisitAllModules(func(module android.Module) {
3005		if javaModule, ok := module.(xref); ok {
3006			xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...)
3007		}
3008	})
3009	// TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets
3010	if len(xrefTargets) > 0 {
3011		ctx.Phony("xref_java", xrefTargets...)
3012	}
3013}
3014
3015var Bool = proptools.Bool
3016var BoolDefault = proptools.BoolDefault
3017var String = proptools.String
3018var inList = android.InList
3019