• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17// This file contains the module types for compiling Java for Android, and converts the properties
18// into the flags and filenames necessary to pass to the Module.  The final creation of the rules
19// is handled in builder.go
20
21import (
22	"fmt"
23	"path/filepath"
24	"strconv"
25	"strings"
26
27	"github.com/google/blueprint"
28	"github.com/google/blueprint/proptools"
29
30	"android/soong/android"
31	"android/soong/java/config"
32	"android/soong/tradefed"
33)
34
35func init() {
36	android.RegisterModuleType("java_defaults", defaultsFactory)
37
38	android.RegisterModuleType("java_library", LibraryFactory)
39	android.RegisterModuleType("java_library_static", LibraryStaticFactory)
40	android.RegisterModuleType("java_library_host", LibraryHostFactory)
41	android.RegisterModuleType("java_binary", BinaryFactory)
42	android.RegisterModuleType("java_binary_host", BinaryHostFactory)
43	android.RegisterModuleType("java_test", TestFactory)
44	android.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory)
45	android.RegisterModuleType("java_test_host", TestHostFactory)
46	android.RegisterModuleType("java_import", ImportFactory)
47	android.RegisterModuleType("java_import_host", ImportFactoryHost)
48	android.RegisterModuleType("java_device_for_host", DeviceForHostFactory)
49	android.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
50	android.RegisterModuleType("dex_import", DexImportFactory)
51
52	android.RegisterSingletonType("logtags", LogtagsSingleton)
53}
54
55// TODO:
56// Autogenerated files:
57//  Renderscript
58// Post-jar passes:
59//  Proguard
60// Rmtypedefs
61// DroidDoc
62// Findbugs
63
64type CompilerProperties struct {
65	// list of source files used to compile the Java module.  May be .java, .logtags, .proto,
66	// or .aidl files.
67	Srcs []string `android:"path,arch_variant"`
68
69	// list of source files that should not be used to build the Java module.
70	// This is most useful in the arch/multilib variants to remove non-common files
71	Exclude_srcs []string `android:"path,arch_variant"`
72
73	// list of directories containing Java resources
74	Java_resource_dirs []string `android:"arch_variant"`
75
76	// list of directories that should be excluded from java_resource_dirs
77	Exclude_java_resource_dirs []string `android:"arch_variant"`
78
79	// list of files to use as Java resources
80	Java_resources []string `android:"path,arch_variant"`
81
82	// list of files that should be excluded from java_resources and java_resource_dirs
83	Exclude_java_resources []string `android:"path,arch_variant"`
84
85	// don't build against the default libraries (bootclasspath, ext, and framework for device
86	// targets)
87	No_standard_libs *bool
88
89	// don't build against the framework libraries (ext, and framework for device targets)
90	No_framework_libs *bool
91
92	// list of module-specific flags that will be used for javac compiles
93	Javacflags []string `android:"arch_variant"`
94
95	// list of module-specific flags that will be used for kotlinc compiles
96	Kotlincflags []string `android:"arch_variant"`
97
98	// list of of java libraries that will be in the classpath
99	Libs []string `android:"arch_variant"`
100
101	// list of java libraries that will be compiled into the resulting jar
102	Static_libs []string `android:"arch_variant"`
103
104	// manifest file to be included in resulting jar
105	Manifest *string `android:"path"`
106
107	// if not blank, run jarjar using the specified rules file
108	Jarjar_rules *string `android:"path,arch_variant"`
109
110	// If not blank, set the java version passed to javac as -source and -target
111	Java_version *string
112
113	// If set to true, allow this module to be dexed and installed on devices.  Has no
114	// effect on host modules, which are always considered installable.
115	Installable *bool
116
117	// If set to true, include sources used to compile the module in to the final jar
118	Include_srcs *bool
119
120	// If not empty, classes are restricted to the specified packages and their sub-packages.
121	// This restriction is checked after applying jarjar rules and including static libs.
122	Permitted_packages []string
123
124	// List of modules to use as annotation processors
125	Plugins []string
126
127	// The number of Java source entries each Javac instance can process
128	Javac_shard_size *int64
129
130	// Add host jdk tools.jar to bootclasspath
131	Use_tools_jar *bool
132
133	Openjdk9 struct {
134		// List of source files that should only be used when passing -source 1.9
135		Srcs []string `android:"path"`
136
137		// List of javac flags that should only be used when passing -source 1.9
138		Javacflags []string
139	}
140
141	// When compiling language level 9+ .java code in packages that are part of
142	// a system module, patch_module names the module that your sources and
143	// dependencies should be patched into. The Android runtime currently
144	// doesn't implement the JEP 261 module system so this option is only
145	// supported at compile time. It should only be needed to compile tests in
146	// packages that exist in libcore and which are inconvenient to move
147	// elsewhere.
148	Patch_module *string `android:"arch_variant"`
149
150	Jacoco struct {
151		// List of classes to include for instrumentation with jacoco to collect coverage
152		// information at runtime when building with coverage enabled.  If unset defaults to all
153		// classes.
154		// Supports '*' as the last character of an entry in the list as a wildcard match.
155		// If preceded by '.' it matches all classes in the package and subpackages, otherwise
156		// it matches classes in the package that have the class name as a prefix.
157		Include_filter []string
158
159		// List of classes to exclude from instrumentation with jacoco to collect coverage
160		// information at runtime when building with coverage enabled.  Overrides classes selected
161		// by the include_filter property.
162		// Supports '*' as the last character of an entry in the list as a wildcard match.
163		// If preceded by '.' it matches all classes in the package and subpackages, otherwise
164		// it matches classes in the package that have the class name as a prefix.
165		Exclude_filter []string
166	}
167
168	Errorprone struct {
169		// List of javac flags that should only be used when running errorprone.
170		Javacflags []string
171	}
172
173	Proto struct {
174		// List of extra options that will be passed to the proto generator.
175		Output_params []string
176	}
177
178	Instrument bool `blueprint:"mutated"`
179
180	// List of files to include in the META-INF/services folder of the resulting jar.
181	Services []string `android:"path,arch_variant"`
182}
183
184type CompilerDeviceProperties struct {
185	// list of module-specific flags that will be used for dex compiles
186	Dxflags []string `android:"arch_variant"`
187
188	// if not blank, set to the version of the sdk to compile against.  Defaults to compiling against the current
189	// sdk if platform_apis is not set.
190	Sdk_version *string
191
192	// if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
193	// Defaults to sdk_version if not set.
194	Min_sdk_version *string
195
196	// if not blank, set the targetSdkVersion in the AndroidManifest.xml.
197	// Defaults to sdk_version if not set.
198	Target_sdk_version *string
199
200	// if true, compile against the platform APIs instead of an SDK.
201	Platform_apis *bool
202
203	Aidl struct {
204		// Top level directories to pass to aidl tool
205		Include_dirs []string
206
207		// Directories rooted at the Android.bp file to pass to aidl tool
208		Local_include_dirs []string
209
210		// directories that should be added as include directories for any aidl sources of modules
211		// that depend on this module, as well as to aidl for this module.
212		Export_include_dirs []string
213
214		// whether to generate traces (for systrace) for this interface
215		Generate_traces *bool
216
217		// whether to generate Binder#GetTransaction name method.
218		Generate_get_transaction_name *bool
219	}
220
221	// If true, export a copy of the module as a -hostdex module for host testing.
222	Hostdex *bool
223
224	Target struct {
225		Hostdex struct {
226			// Additional required dependencies to add to -hostdex modules.
227			Required []string
228		}
229	}
230
231	// If set to true, compile dex regardless of installable.  Defaults to false.
232	Compile_dex *bool
233
234	Optimize struct {
235		// If false, disable all optimization.  Defaults to true for android_app and android_test
236		// modules, false for java_library and java_test modules.
237		Enabled *bool
238		// True if the module containing this has it set by default.
239		EnabledByDefault bool `blueprint:"mutated"`
240
241		// If true, optimize for size by removing unused code.  Defaults to true for apps,
242		// false for libraries and tests.
243		Shrink *bool
244
245		// If true, optimize bytecode.  Defaults to false.
246		Optimize *bool
247
248		// If true, obfuscate bytecode.  Defaults to false.
249		Obfuscate *bool
250
251		// If true, do not use the flag files generated by aapt that automatically keep
252		// classes referenced by the app manifest.  Defaults to false.
253		No_aapt_flags *bool
254
255		// Flags to pass to proguard.
256		Proguard_flags []string
257
258		// Specifies the locations of files containing proguard flags.
259		Proguard_flags_files []string `android:"path"`
260	}
261
262	// When targeting 1.9, override the modules to use with --system
263	System_modules *string
264
265	UncompressDex bool `blueprint:"mutated"`
266	IsSDKLibrary  bool `blueprint:"mutated"`
267}
268
269func (me *CompilerDeviceProperties) EffectiveOptimizeEnabled() bool {
270	return BoolDefault(me.Optimize.Enabled, me.Optimize.EnabledByDefault)
271}
272
273// Module contains the properties and members used by all java module types
274type Module struct {
275	android.ModuleBase
276	android.DefaultableModuleBase
277
278	properties       CompilerProperties
279	protoProperties  android.ProtoProperties
280	deviceProperties CompilerDeviceProperties
281
282	// jar file containing header classes including static library dependencies, suitable for
283	// inserting into the bootclasspath/classpath of another compile
284	headerJarFile android.Path
285
286	// jar file containing implementation classes including static library dependencies but no
287	// resources
288	implementationJarFile android.Path
289
290	// jar file containing only resources including from static library dependencies
291	resourceJar android.Path
292
293	// jar file containing implementation classes and resources including static library
294	// dependencies
295	implementationAndResourcesJar android.Path
296
297	// output file containing classes.dex and resources
298	dexJarFile android.Path
299
300	// output file that contains classes.dex if it should be in the output file
301	maybeStrippedDexJarFile android.Path
302
303	// output file containing uninstrumented classes that will be instrumented by jacoco
304	jacocoReportClassesFile android.Path
305
306	// output file containing mapping of obfuscated names
307	proguardDictionary android.Path
308
309	// output file of the module, which may be a classes jar or a dex jar
310	outputFile       android.Path
311	extraOutputFiles android.Paths
312
313	exportAidlIncludeDirs android.Paths
314
315	logtagsSrcs android.Paths
316
317	// installed file for binary dependency
318	installFile android.Path
319
320	// list of .java files and srcjars that was passed to javac
321	compiledJavaSrcs android.Paths
322	compiledSrcJars  android.Paths
323
324	// list of extra progurad flag files
325	extraProguardFlagFiles android.Paths
326
327	// manifest file to use instead of properties.Manifest
328	overrideManifest android.OptionalPath
329
330	// list of SDK lib names that this java moudule is exporting
331	exportedSdkLibs []string
332
333	// list of source files, collected from compiledJavaSrcs and compiledSrcJars
334	// filter out Exclude_srcs, will be used by android.IDEInfo struct
335	expandIDEInfoCompiledSrcs []string
336
337	// expanded Jarjar_rules
338	expandJarjarRules android.Path
339
340	// list of additional targets for checkbuild
341	additionalCheckedModules android.Paths
342
343	hiddenAPI
344	dexpreopter
345}
346
347func (j *Module) Srcs() android.Paths {
348	return append(android.Paths{j.outputFile}, j.extraOutputFiles...)
349}
350
351func (j *Module) DexJarFile() android.Path {
352	return j.dexJarFile
353}
354
355var _ android.SourceFileProducer = (*Module)(nil)
356
357type Dependency interface {
358	HeaderJars() android.Paths
359	ImplementationJars() android.Paths
360	ResourceJars() android.Paths
361	ImplementationAndResourcesJars() android.Paths
362	DexJar() android.Path
363	AidlIncludeDirs() android.Paths
364	ExportedSdkLibs() []string
365}
366
367type SdkLibraryDependency interface {
368	SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths
369	SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths
370}
371
372type SrcDependency interface {
373	CompiledSrcs() android.Paths
374	CompiledSrcJars() android.Paths
375}
376
377func (j *Module) CompiledSrcs() android.Paths {
378	return j.compiledJavaSrcs
379}
380
381func (j *Module) CompiledSrcJars() android.Paths {
382	return j.compiledSrcJars
383}
384
385var _ SrcDependency = (*Module)(nil)
386
387func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
388	android.InitAndroidArchModule(module, hod, android.MultilibCommon)
389	android.InitDefaultableModule(module)
390}
391
392type dependencyTag struct {
393	blueprint.BaseDependencyTag
394	name string
395}
396
397type jniDependencyTag struct {
398	blueprint.BaseDependencyTag
399	target android.Target
400}
401
402var (
403	staticLibTag          = dependencyTag{name: "staticlib"}
404	libTag                = dependencyTag{name: "javalib"}
405	pluginTag             = dependencyTag{name: "plugin"}
406	bootClasspathTag      = dependencyTag{name: "bootclasspath"}
407	systemModulesTag      = dependencyTag{name: "system modules"}
408	frameworkResTag       = dependencyTag{name: "framework-res"}
409	frameworkApkTag       = dependencyTag{name: "framework-apk"}
410	kotlinStdlibTag       = dependencyTag{name: "kotlin-stdlib"}
411	kotlinAnnotationsTag  = dependencyTag{name: "kotlin-annotations"}
412	proguardRaiseTag      = dependencyTag{name: "proguard-raise"}
413	certificateTag        = dependencyTag{name: "certificate"}
414	instrumentationForTag = dependencyTag{name: "instrumentation_for"}
415)
416
417type sdkDep struct {
418	useModule, useFiles, useDefaultLibs, invalidVersion bool
419
420	modules       []string
421	systemModules string
422
423	frameworkResModule string
424
425	jars android.Paths
426	aidl android.OptionalPath
427}
428
429type jniLib struct {
430	name   string
431	path   android.Path
432	target android.Target
433}
434
435func (j *Module) shouldInstrument(ctx android.BaseContext) bool {
436	return j.properties.Instrument && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT")
437}
438
439func (j *Module) shouldInstrumentStatic(ctx android.BaseContext) bool {
440	return j.shouldInstrument(ctx) &&
441		(ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_STATIC") ||
442			ctx.Config().UnbundledBuild())
443}
444
445func (j *Module) sdkVersion() string {
446	return String(j.deviceProperties.Sdk_version)
447}
448
449func (j *Module) minSdkVersion() string {
450	if j.deviceProperties.Min_sdk_version != nil {
451		return *j.deviceProperties.Min_sdk_version
452	}
453	return j.sdkVersion()
454}
455
456func (j *Module) targetSdkVersion() string {
457	if j.deviceProperties.Target_sdk_version != nil {
458		return *j.deviceProperties.Target_sdk_version
459	}
460	return j.sdkVersion()
461}
462
463func (j *Module) deps(ctx android.BottomUpMutatorContext) {
464	if ctx.Device() {
465		if !Bool(j.properties.No_standard_libs) {
466			sdkDep := decodeSdkDep(ctx, sdkContext(j))
467			if sdkDep.useDefaultLibs {
468				ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
469				ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
470				if !Bool(j.properties.No_framework_libs) {
471					ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
472				}
473			} else if sdkDep.useModule {
474				ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
475				ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
476				if j.deviceProperties.EffectiveOptimizeEnabled() {
477					ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultBootclasspathLibraries...)
478					ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultLibraries...)
479				}
480			}
481		} else if j.deviceProperties.System_modules == nil {
482			ctx.PropertyErrorf("no_standard_libs",
483				"system_modules is required to be set when no_standard_libs is true, did you mean no_framework_libs?")
484		} else if *j.deviceProperties.System_modules != "none" {
485			ctx.AddVariationDependencies(nil, systemModulesTag, *j.deviceProperties.System_modules)
486		}
487		if (ctx.ModuleName() == "framework") || (ctx.ModuleName() == "framework-annotation-proc") {
488			ctx.AddVariationDependencies(nil, frameworkResTag, "framework-res")
489		}
490		if ctx.ModuleName() == "android_stubs_current" ||
491			ctx.ModuleName() == "android_system_stubs_current" ||
492			ctx.ModuleName() == "android_test_stubs_current" {
493			ctx.AddVariationDependencies(nil, frameworkApkTag, "framework-res")
494		}
495	}
496
497	ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
498	ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...)
499
500	ctx.AddFarVariationDependencies([]blueprint.Variation{
501		{Mutator: "arch", Variation: ctx.Config().BuildOsCommonVariant},
502	}, pluginTag, j.properties.Plugins...)
503
504	android.ProtoDeps(ctx, &j.protoProperties)
505	if j.hasSrcExt(".proto") {
506		protoDeps(ctx, &j.protoProperties)
507	}
508
509	if j.hasSrcExt(".kt") {
510		// TODO(ccross): move this to a mutator pass that can tell if generated sources contain
511		// Kotlin files
512		ctx.AddVariationDependencies(nil, kotlinStdlibTag, "kotlin-stdlib")
513		if len(j.properties.Plugins) > 0 {
514			ctx.AddVariationDependencies(nil, kotlinAnnotationsTag, "kotlin-annotations")
515		}
516	}
517
518	if j.shouldInstrumentStatic(ctx) {
519		ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
520	}
521}
522
523func hasSrcExt(srcs []string, ext string) bool {
524	for _, src := range srcs {
525		if filepath.Ext(src) == ext {
526			return true
527		}
528	}
529
530	return false
531}
532
533func shardPaths(paths android.Paths, shardSize int) []android.Paths {
534	ret := make([]android.Paths, 0, (len(paths)+shardSize-1)/shardSize)
535	for len(paths) > shardSize {
536		ret = append(ret, paths[0:shardSize])
537		paths = paths[shardSize:]
538	}
539	if len(paths) > 0 {
540		ret = append(ret, paths)
541	}
542	return ret
543}
544
545func (j *Module) hasSrcExt(ext string) bool {
546	return hasSrcExt(j.properties.Srcs, ext)
547}
548
549func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
550	aidlIncludeDirs android.Paths) (string, android.Paths) {
551
552	aidlIncludes := android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Local_include_dirs)
553	aidlIncludes = append(aidlIncludes,
554		android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)...)
555	aidlIncludes = append(aidlIncludes,
556		android.PathsForSource(ctx, j.deviceProperties.Aidl.Include_dirs)...)
557
558	var flags []string
559	var deps android.Paths
560
561	if aidlPreprocess.Valid() {
562		flags = append(flags, "-p"+aidlPreprocess.String())
563		deps = append(deps, aidlPreprocess.Path())
564	} else if len(aidlIncludeDirs) > 0 {
565		flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
566	}
567
568	if len(j.exportAidlIncludeDirs) > 0 {
569		flags = append(flags, android.JoinWithPrefix(j.exportAidlIncludeDirs.Strings(), "-I"))
570	}
571
572	if len(aidlIncludes) > 0 {
573		flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
574	}
575
576	flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
577	if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
578		flags = append(flags, "-I"+src.String())
579	}
580
581	if Bool(j.deviceProperties.Aidl.Generate_traces) {
582		flags = append(flags, "-t")
583	}
584
585	if Bool(j.deviceProperties.Aidl.Generate_get_transaction_name) {
586		flags = append(flags, "--transaction_names")
587	}
588
589	return strings.Join(flags, " "), deps
590}
591
592type deps struct {
593	classpath          classpath
594	bootClasspath      classpath
595	processorPath      classpath
596	processorClasses   []string
597	staticJars         android.Paths
598	staticHeaderJars   android.Paths
599	staticResourceJars android.Paths
600	aidlIncludeDirs    android.Paths
601	srcs               android.Paths
602	srcJars            android.Paths
603	systemModules      android.Path
604	aidlPreprocess     android.OptionalPath
605	kotlinStdlib       android.Paths
606	kotlinAnnotations  android.Paths
607
608	disableTurbine bool
609}
610
611func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) {
612	for _, f := range dep.Srcs() {
613		if f.Ext() != ".jar" {
614			ctx.ModuleErrorf("genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency",
615				ctx.OtherModuleName(dep.(blueprint.Module)))
616		}
617	}
618}
619
620type linkType int
621
622const (
623	javaCore linkType = iota
624	javaSdk
625	javaSystem
626	javaPlatform
627)
628
629func getLinkType(m *Module, name string) (ret linkType, stubs bool) {
630	ver := m.sdkVersion()
631	switch {
632	case name == "core.current.stubs" || name == "core.platform.api.stubs" ||
633		name == "stub-annotations" || name == "private-stub-annotations-jar" ||
634		name == "core-lambda-stubs":
635		return javaCore, true
636	case ver == "core_current":
637		return javaCore, false
638	case name == "android_system_stubs_current":
639		return javaSystem, true
640	case strings.HasPrefix(ver, "system_"):
641		return javaSystem, false
642	case name == "android_test_stubs_current":
643		return javaSystem, true
644	case strings.HasPrefix(ver, "test_"):
645		return javaPlatform, false
646	case name == "android_stubs_current":
647		return javaSdk, true
648	case ver == "current":
649		return javaSdk, false
650	case ver == "":
651		return javaPlatform, false
652	default:
653		if _, err := strconv.Atoi(ver); err != nil {
654			panic(fmt.Errorf("expected sdk_version to be a number, got %q", ver))
655		}
656		return javaSdk, false
657	}
658}
659
660func checkLinkType(ctx android.ModuleContext, from *Module, to *Library, tag dependencyTag) {
661	if ctx.Host() {
662		return
663	}
664
665	myLinkType, stubs := getLinkType(from, ctx.ModuleName())
666	if stubs {
667		return
668	}
669	otherLinkType, _ := getLinkType(&to.Module, ctx.OtherModuleName(to))
670	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."
671
672	switch myLinkType {
673	case javaCore:
674		if otherLinkType != javaCore {
675			ctx.ModuleErrorf("compiles against core Java API, but dependency %q is compiling against non-core Java APIs."+commonMessage,
676				ctx.OtherModuleName(to))
677		}
678		break
679	case javaSdk:
680		if otherLinkType != javaCore && otherLinkType != javaSdk {
681			ctx.ModuleErrorf("compiles against Android API, but dependency %q is compiling against non-public Android API."+commonMessage,
682				ctx.OtherModuleName(to))
683		}
684		break
685	case javaSystem:
686		if otherLinkType == javaPlatform {
687			ctx.ModuleErrorf("compiles against system API, but dependency %q is compiling against private API."+commonMessage,
688				ctx.OtherModuleName(to))
689		}
690		break
691	case javaPlatform:
692		// no restriction on link-type
693		break
694	}
695}
696
697func (j *Module) collectDeps(ctx android.ModuleContext) deps {
698	var deps deps
699
700	if ctx.Device() {
701		sdkDep := decodeSdkDep(ctx, sdkContext(j))
702		if sdkDep.invalidVersion {
703			ctx.AddMissingDependencies(sdkDep.modules)
704		} else if sdkDep.useFiles {
705			// sdkDep.jar is actually equivalent to turbine header.jar.
706			deps.classpath = append(deps.classpath, sdkDep.jars...)
707			deps.aidlPreprocess = sdkDep.aidl
708		} else {
709			deps.aidlPreprocess = sdkDep.aidl
710		}
711	}
712
713	ctx.VisitDirectDeps(func(module android.Module) {
714		otherName := ctx.OtherModuleName(module)
715		tag := ctx.OtherModuleDependencyTag(module)
716
717		if _, ok := tag.(*jniDependencyTag); ok {
718			// Handled by AndroidApp.collectAppDeps
719			return
720		}
721		if tag == certificateTag {
722			// Handled by AndroidApp.collectAppDeps
723			return
724		}
725
726		if to, ok := module.(*Library); ok {
727			switch tag {
728			case bootClasspathTag, libTag, staticLibTag:
729				checkLinkType(ctx, j, to, tag.(dependencyTag))
730			}
731		}
732		switch dep := module.(type) {
733		case SdkLibraryDependency:
734			switch tag {
735			case libTag:
736				deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
737				// names of sdk libs that are directly depended are exported
738				j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
739			default:
740				ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
741			}
742		case Dependency:
743			switch tag {
744			case bootClasspathTag:
745				deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
746			case libTag, instrumentationForTag:
747				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
748				// sdk lib names from dependencies are re-exported
749				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
750				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
751			case staticLibTag:
752				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
753				deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
754				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
755				deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars()...)
756				// sdk lib names from dependencies are re-exported
757				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
758				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
759			case pluginTag:
760				if plugin, ok := dep.(*Plugin); ok {
761					deps.processorPath = append(deps.processorPath, dep.ImplementationAndResourcesJars()...)
762					if plugin.pluginProperties.Processor_class != nil {
763						deps.processorClasses = append(deps.processorClasses, *plugin.pluginProperties.Processor_class)
764					}
765					deps.disableTurbine = deps.disableTurbine || Bool(plugin.pluginProperties.Generates_api)
766				} else {
767					ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
768				}
769			case frameworkResTag:
770				if (ctx.ModuleName() == "framework") || (ctx.ModuleName() == "framework-annotation-proc") {
771					// framework.jar has a one-off dependency on the R.java and Manifest.java files
772					// generated by framework-res.apk
773					deps.srcJars = append(deps.srcJars, dep.(*AndroidApp).aaptSrcJar)
774				}
775			case frameworkApkTag:
776				if ctx.ModuleName() == "android_stubs_current" ||
777					ctx.ModuleName() == "android_system_stubs_current" ||
778					ctx.ModuleName() == "android_test_stubs_current" {
779					// framework stubs.jar need to depend on framework-res.apk, in order to pull the
780					// resource files out of there for aapt.
781					//
782					// Normally the package rule runs aapt, which includes the resource,
783					// but we're not running that in our package rule so just copy in the
784					// resource files here.
785					deps.staticResourceJars = append(deps.staticResourceJars, dep.(*AndroidApp).exportPackage)
786				}
787			case kotlinStdlibTag:
788				deps.kotlinStdlib = dep.HeaderJars()
789			case kotlinAnnotationsTag:
790				deps.kotlinAnnotations = dep.HeaderJars()
791			}
792
793		case android.SourceFileProducer:
794			switch tag {
795			case libTag:
796				checkProducesJars(ctx, dep)
797				deps.classpath = append(deps.classpath, dep.Srcs()...)
798			case staticLibTag:
799				checkProducesJars(ctx, dep)
800				deps.classpath = append(deps.classpath, dep.Srcs()...)
801				deps.staticJars = append(deps.staticJars, dep.Srcs()...)
802				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
803			}
804		default:
805			switch tag {
806			case android.DefaultsDepTag, android.SourceDepTag:
807				// Nothing to do
808			case systemModulesTag:
809				if deps.systemModules != nil {
810					panic("Found two system module dependencies")
811				}
812				sm := module.(*SystemModules)
813				if sm.outputFile == nil {
814					panic("Missing directory for system module dependency")
815				}
816				deps.systemModules = sm.outputFile
817			default:
818				ctx.ModuleErrorf("depends on non-java module %q", otherName)
819			}
820		}
821	})
822
823	j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)
824
825	return deps
826}
827
828func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) string {
829	var ret string
830	v := sdkContext.sdkVersion()
831	// For PDK builds, use the latest SDK version instead of "current"
832	if ctx.Config().IsPdkBuild() && (v == "" || v == "current") {
833		sdkVersions := ctx.Config().Get(sdkVersionsKey).([]int)
834		latestSdkVersion := 0
835		if len(sdkVersions) > 0 {
836			latestSdkVersion = sdkVersions[len(sdkVersions)-1]
837		}
838		v = strconv.Itoa(latestSdkVersion)
839	}
840
841	sdk, err := sdkVersionToNumber(ctx, v)
842	if err != nil {
843		ctx.PropertyErrorf("sdk_version", "%s", err)
844	}
845	if javaVersion != "" {
846		ret = javaVersion
847	} else if ctx.Device() && sdk <= 23 {
848		ret = "1.7"
849	} else if ctx.Device() && sdk <= 28 || !ctx.Config().TargetOpenJDK9() {
850		ret = "1.8"
851	} else if ctx.Device() && sdkContext.sdkVersion() != "" && sdk == android.FutureApiLevel {
852		// TODO(ccross): once we generate stubs we should be able to use 1.9 for sdk_version: "current"
853		ret = "1.8"
854	} else {
855		ret = "1.9"
856	}
857
858	return ret
859}
860
861func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags {
862
863	var flags javaBuilderFlags
864
865	// javaVersion flag.
866	flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
867
868	// javac flags.
869	javacFlags := j.properties.Javacflags
870	if flags.javaVersion == "1.9" {
871		javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
872	}
873	if ctx.Config().MinimizeJavaDebugInfo() {
874		// Override the -g flag passed globally to remove local variable debug info to reduce
875		// disk and memory usage.
876		javacFlags = append(javacFlags, "-g:source,lines")
877	}
878
879	if ctx.Config().RunErrorProne() {
880		if config.ErrorProneClasspath == nil {
881			ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
882		}
883
884		errorProneFlags := []string{
885			"-Xplugin:ErrorProne",
886			"${config.ErrorProneChecks}",
887		}
888		errorProneFlags = append(errorProneFlags, j.properties.Errorprone.Javacflags...)
889
890		flags.errorProneExtraJavacFlags = "${config.ErrorProneFlags} " +
891			"'" + strings.Join(errorProneFlags, " ") + "'"
892		flags.errorProneProcessorPath = classpath(android.PathsForSource(ctx, config.ErrorProneClasspath))
893	}
894
895	// classpath
896	flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...)
897	flags.classpath = append(flags.classpath, deps.classpath...)
898	flags.processorPath = append(flags.processorPath, deps.processorPath...)
899
900	flags.processor = strings.Join(deps.processorClasses, ",")
901
902	if len(flags.bootClasspath) == 0 && ctx.Host() && flags.javaVersion != "1.9" &&
903		!Bool(j.properties.No_standard_libs) &&
904		inList(flags.javaVersion, []string{"1.6", "1.7", "1.8"}) {
905		// Give host-side tools a version of OpenJDK's standard libraries
906		// close to what they're targeting. As of Dec 2017, AOSP is only
907		// bundling OpenJDK 8 and 9, so nothing < 8 is available.
908		//
909		// When building with OpenJDK 8, the following should have no
910		// effect since those jars would be available by default.
911		//
912		// When building with OpenJDK 9 but targeting a version < 1.8,
913		// putting them on the bootclasspath means that:
914		// a) code can't (accidentally) refer to OpenJDK 9 specific APIs
915		// b) references to existing APIs are not reinterpreted in an
916		//    OpenJDK 9-specific way, eg. calls to subclasses of
917		//    java.nio.Buffer as in http://b/70862583
918		java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
919		flags.bootClasspath = append(flags.bootClasspath,
920			android.PathForSource(ctx, java8Home, "jre/lib/jce.jar"),
921			android.PathForSource(ctx, java8Home, "jre/lib/rt.jar"))
922		if Bool(j.properties.Use_tools_jar) {
923			flags.bootClasspath = append(flags.bootClasspath,
924				android.PathForSource(ctx, java8Home, "lib/tools.jar"))
925		}
926	}
927
928	if j.properties.Patch_module != nil && flags.javaVersion == "1.9" {
929		// Manually specify build directory in case it is not under the repo root.
930		// (javac doesn't seem to expand into symbolc links when searching for patch-module targets, so
931		// just adding a symlink under the root doesn't help.)
932		patchPaths := ".:" + ctx.Config().BuildDir()
933		classPath := flags.classpath.FormJavaClassPath("")
934		if classPath != "" {
935			patchPaths += ":" + classPath
936		}
937		javacFlags = append(javacFlags, "--patch-module="+String(j.properties.Patch_module)+"="+patchPaths)
938	}
939
940	// systemModules
941	if deps.systemModules != nil {
942		flags.systemModules = append(flags.systemModules, deps.systemModules)
943	}
944
945	// aidl flags.
946	flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
947
948	if len(javacFlags) > 0 {
949		// optimization.
950		ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
951		flags.javacFlags = "$javacFlags"
952	}
953
954	return flags
955}
956
957func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path) {
958
959	j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)
960
961	deps := j.collectDeps(ctx)
962	flags := j.collectBuilderFlags(ctx, deps)
963
964	if flags.javaVersion == "1.9" {
965		j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
966	}
967	srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
968	if hasSrcExt(srcFiles.Strings(), ".proto") {
969		flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags)
970	}
971
972	srcFiles = j.genSources(ctx, srcFiles, flags)
973
974	srcJars := srcFiles.FilterByExt(".srcjar")
975	srcJars = append(srcJars, deps.srcJars...)
976	srcJars = append(srcJars, extraSrcJars...)
977
978	// Collect source files from compiledJavaSrcs, compiledSrcJars and filter out Exclude_srcs
979	// that IDEInfo struct will use
980	j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.Strings()...)
981
982	if j.properties.Jarjar_rules != nil {
983		j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
984	}
985
986	jarName := ctx.ModuleName() + ".jar"
987
988	javaSrcFiles := srcFiles.FilterByExt(".java")
989	var uniqueSrcFiles android.Paths
990	set := make(map[string]bool)
991	for _, v := range javaSrcFiles {
992		if _, found := set[v.String()]; !found {
993			set[v.String()] = true
994			uniqueSrcFiles = append(uniqueSrcFiles, v)
995		}
996	}
997
998	var kotlinJars android.Paths
999
1000	if srcFiles.HasExt(".kt") {
1001		// user defined kotlin flags.
1002		kotlincFlags := j.properties.Kotlincflags
1003		CheckKotlincFlags(ctx, kotlincFlags)
1004
1005		// If there are kotlin files, compile them first but pass all the kotlin and java files
1006		// kotlinc will use the java files to resolve types referenced by the kotlin files, but
1007		// won't emit any classes for them.
1008		kotlincFlags = append(kotlincFlags, "-no-stdlib")
1009		if ctx.Device() {
1010			kotlincFlags = append(kotlincFlags, "-no-jdk")
1011		}
1012		if len(kotlincFlags) > 0 {
1013			// optimization.
1014			ctx.Variable(pctx, "kotlincFlags", strings.Join(kotlincFlags, " "))
1015			flags.kotlincFlags += "$kotlincFlags"
1016		}
1017
1018		var kotlinSrcFiles android.Paths
1019		kotlinSrcFiles = append(kotlinSrcFiles, uniqueSrcFiles...)
1020		kotlinSrcFiles = append(kotlinSrcFiles, srcFiles.FilterByExt(".kt")...)
1021
1022		flags.classpath = append(flags.classpath, deps.kotlinStdlib...)
1023		flags.classpath = append(flags.classpath, deps.kotlinAnnotations...)
1024
1025		flags.kotlincClasspath = append(flags.kotlincClasspath, flags.bootClasspath...)
1026		flags.kotlincClasspath = append(flags.kotlincClasspath, flags.classpath...)
1027
1028		if len(flags.processorPath) > 0 {
1029			// Use kapt for annotation processing
1030			kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar")
1031			kotlinKapt(ctx, kaptSrcJar, kotlinSrcFiles, srcJars, flags)
1032			srcJars = append(srcJars, kaptSrcJar)
1033			// Disable annotation processing in javac, it's already been handled by kapt
1034			flags.processorPath = nil
1035			flags.processor = ""
1036		}
1037
1038		kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
1039		kotlinCompile(ctx, kotlinJar, kotlinSrcFiles, srcJars, flags)
1040		if ctx.Failed() {
1041			return
1042		}
1043
1044		// Make javac rule depend on the kotlinc rule
1045		flags.classpath = append(flags.classpath, kotlinJar)
1046
1047		// Jar kotlin classes into the final jar after javac
1048		kotlinJars = append(kotlinJars, kotlinJar)
1049		kotlinJars = append(kotlinJars, deps.kotlinStdlib...)
1050	}
1051
1052	jars := append(android.Paths(nil), kotlinJars...)
1053
1054	// Store the list of .java files that was passed to javac
1055	j.compiledJavaSrcs = uniqueSrcFiles
1056	j.compiledSrcJars = srcJars
1057
1058	enable_sharding := false
1059	if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !deps.disableTurbine {
1060		if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
1061			enable_sharding = true
1062			// Formerly, there was a check here that prevented annotation processors
1063			// from being used when sharding was enabled, as some annotation processors
1064			// do not function correctly in sharded environments. It was removed to
1065			// allow for the use of annotation processors that do function correctly
1066			// with sharding enabled. See: b/77284273.
1067		}
1068		j.headerJarFile = j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinJars)
1069		if ctx.Failed() {
1070			return
1071		}
1072	}
1073	if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 {
1074		var extraJarDeps android.Paths
1075		if ctx.Config().RunErrorProne() {
1076			// If error-prone is enabled, add an additional rule to compile the java files into
1077			// a separate set of classes (so that they don't overwrite the normal ones and require
1078			// a rebuild when error-prone is turned off).
1079			// TODO(ccross): Once we always compile with javac9 we may be able to conditionally
1080			//    enable error-prone without affecting the output class files.
1081			errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
1082			RunErrorProne(ctx, errorprone, uniqueSrcFiles, srcJars, flags)
1083			extraJarDeps = append(extraJarDeps, errorprone)
1084		}
1085
1086		if enable_sharding {
1087			flags.classpath = append(flags.classpath, j.headerJarFile)
1088			shardSize := int(*(j.properties.Javac_shard_size))
1089			var shardSrcs []android.Paths
1090			if len(uniqueSrcFiles) > 0 {
1091				shardSrcs = shardPaths(uniqueSrcFiles, shardSize)
1092				for idx, shardSrc := range shardSrcs {
1093					classes := android.PathForModuleOut(ctx, "javac", jarName+strconv.Itoa(idx))
1094					TransformJavaToClasses(ctx, classes, idx, shardSrc, nil, flags, extraJarDeps)
1095					jars = append(jars, classes)
1096				}
1097			}
1098			if len(srcJars) > 0 {
1099				classes := android.PathForModuleOut(ctx, "javac", jarName+strconv.Itoa(len(shardSrcs)))
1100				TransformJavaToClasses(ctx, classes, len(shardSrcs), nil, srcJars, flags, extraJarDeps)
1101				jars = append(jars, classes)
1102			}
1103		} else {
1104			classes := android.PathForModuleOut(ctx, "javac", jarName)
1105			TransformJavaToClasses(ctx, classes, -1, uniqueSrcFiles, srcJars, flags, extraJarDeps)
1106			jars = append(jars, classes)
1107		}
1108		if ctx.Failed() {
1109			return
1110		}
1111	}
1112
1113	dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs,
1114		j.properties.Exclude_java_resource_dirs, j.properties.Exclude_java_resources)
1115	fileArgs, fileDeps := ResourceFilesToJarArgs(ctx, j.properties.Java_resources, j.properties.Exclude_java_resources)
1116
1117	var resArgs []string
1118	var resDeps android.Paths
1119
1120	resArgs = append(resArgs, dirArgs...)
1121	resDeps = append(resDeps, dirDeps...)
1122
1123	resArgs = append(resArgs, fileArgs...)
1124	resDeps = append(resDeps, fileDeps...)
1125
1126	if Bool(j.properties.Include_srcs) {
1127		srcArgs, srcDeps := SourceFilesToJarArgs(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
1128		resArgs = append(resArgs, srcArgs...)
1129		resDeps = append(resDeps, srcDeps...)
1130	}
1131
1132	if len(resArgs) > 0 {
1133		resourceJar := android.PathForModuleOut(ctx, "res", jarName)
1134		TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
1135		j.resourceJar = resourceJar
1136		if ctx.Failed() {
1137			return
1138		}
1139	}
1140
1141	if len(deps.staticResourceJars) > 0 {
1142		var jars android.Paths
1143		if j.resourceJar != nil {
1144			jars = append(jars, j.resourceJar)
1145		}
1146		jars = append(jars, deps.staticResourceJars...)
1147
1148		combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
1149		TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{},
1150			false, nil, nil)
1151		j.resourceJar = combinedJar
1152	}
1153
1154	jars = append(jars, deps.staticJars...)
1155
1156	manifest := j.overrideManifest
1157	if !manifest.Valid() && j.properties.Manifest != nil {
1158		manifest = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *j.properties.Manifest))
1159	}
1160
1161	services := android.PathsForModuleSrc(ctx, j.properties.Services)
1162	if len(services) > 0 {
1163		servicesJar := android.PathForModuleOut(ctx, "services", jarName)
1164		var zipargs []string
1165		for _, file := range services {
1166			serviceFile := file.String()
1167			zipargs = append(zipargs, "-C", filepath.Dir(serviceFile), "-f", serviceFile)
1168		}
1169		ctx.Build(pctx, android.BuildParams{
1170			Rule:      zip,
1171			Output:    servicesJar,
1172			Implicits: services,
1173			Args: map[string]string{
1174				"jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "),
1175			},
1176		})
1177		jars = append(jars, servicesJar)
1178	}
1179
1180	// Combine the classes built from sources, any manifests, and any static libraries into
1181	// classes.jar. If there is only one input jar this step will be skipped.
1182	var outputFile android.ModuleOutPath
1183
1184	if len(jars) == 1 && !manifest.Valid() {
1185		if moduleOutPath, ok := jars[0].(android.ModuleOutPath); ok {
1186			// Optimization: skip the combine step if there is nothing to do
1187			// TODO(ccross): this leaves any module-info.class files, but those should only come from
1188			// prebuilt dependencies until we support modules in the platform build, so there shouldn't be
1189			// any if len(jars) == 1.
1190			outputFile = moduleOutPath
1191		} else {
1192			combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
1193			ctx.Build(pctx, android.BuildParams{
1194				Rule:   android.Cp,
1195				Input:  jars[0],
1196				Output: combinedJar,
1197			})
1198			outputFile = combinedJar
1199		}
1200	} else {
1201		combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
1202		TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest,
1203			false, nil, nil)
1204		outputFile = combinedJar
1205	}
1206
1207	// jarjar implementation jar if necessary
1208	if j.expandJarjarRules != nil {
1209		// Transform classes.jar into classes-jarjar.jar
1210		jarjarFile := android.PathForModuleOut(ctx, "jarjar", jarName)
1211		TransformJarJar(ctx, jarjarFile, outputFile, j.expandJarjarRules)
1212		outputFile = jarjarFile
1213
1214		// jarjar resource jar if necessary
1215		if j.resourceJar != nil {
1216			resourceJarJarFile := android.PathForModuleOut(ctx, "res-jarjar", jarName)
1217			TransformJarJar(ctx, resourceJarJarFile, j.resourceJar, j.expandJarjarRules)
1218			j.resourceJar = resourceJarJarFile
1219		}
1220
1221		if ctx.Failed() {
1222			return
1223		}
1224	}
1225
1226	// Check package restrictions if necessary.
1227	if len(j.properties.Permitted_packages) > 0 {
1228		// Check packages and copy to package-checked file.
1229		pkgckFile := android.PathForModuleOut(ctx, "package-check.stamp")
1230		CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages)
1231		j.additionalCheckedModules = append(j.additionalCheckedModules, pkgckFile)
1232
1233		if ctx.Failed() {
1234			return
1235		}
1236	}
1237
1238	j.implementationJarFile = outputFile
1239	if j.headerJarFile == nil {
1240		j.headerJarFile = j.implementationJarFile
1241	}
1242
1243	if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
1244		if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
1245			j.properties.Instrument = true
1246		}
1247	}
1248
1249	if j.shouldInstrument(ctx) {
1250		outputFile = j.instrument(ctx, flags, outputFile, jarName)
1251	}
1252
1253	// merge implementation jar with resources if necessary
1254	implementationAndResourcesJar := outputFile
1255	if j.resourceJar != nil {
1256		jars := android.Paths{implementationAndResourcesJar, j.resourceJar}
1257		combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
1258		TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{},
1259			false, nil, nil)
1260		implementationAndResourcesJar = combinedJar
1261	}
1262
1263	j.implementationAndResourcesJar = implementationAndResourcesJar
1264
1265	if ctx.Device() && (Bool(j.properties.Installable) || Bool(j.deviceProperties.Compile_dex)) {
1266		// Dex compilation
1267		var dexOutputFile android.ModuleOutPath
1268		dexOutputFile = j.compileDex(ctx, flags, outputFile, jarName)
1269		if ctx.Failed() {
1270			return
1271		}
1272
1273		// Hidden API CSV generation and dex encoding
1274		dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, dexOutputFile, j.implementationJarFile,
1275			j.deviceProperties.UncompressDex)
1276
1277		// merge dex jar with resources if necessary
1278		if j.resourceJar != nil {
1279			jars := android.Paths{dexOutputFile, j.resourceJar}
1280			combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
1281			TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{},
1282				false, nil, nil)
1283			if j.deviceProperties.UncompressDex {
1284				combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName)
1285				TransformZipAlign(ctx, combinedAlignedJar, combinedJar)
1286				dexOutputFile = combinedAlignedJar
1287			} else {
1288				dexOutputFile = combinedJar
1289			}
1290		}
1291
1292		j.dexJarFile = dexOutputFile
1293
1294		// Dexpreopting
1295		dexOutputFile = j.dexpreopt(ctx, dexOutputFile)
1296
1297		j.maybeStrippedDexJarFile = dexOutputFile
1298
1299		outputFile = dexOutputFile
1300
1301		if ctx.Failed() {
1302			return
1303		}
1304	} else {
1305		outputFile = implementationAndResourcesJar
1306	}
1307
1308	ctx.CheckbuildFile(outputFile)
1309
1310	// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
1311	j.outputFile = outputFile.WithoutRel()
1312}
1313
1314// Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user,
1315// since some of these flags may be used internally.
1316func CheckKotlincFlags(ctx android.ModuleContext, flags []string) {
1317	for _, flag := range flags {
1318		flag = strings.TrimSpace(flag)
1319
1320		if !strings.HasPrefix(flag, "-") {
1321			ctx.PropertyErrorf("kotlincflags", "Flag `%s` must start with `-`", flag)
1322		} else if strings.HasPrefix(flag, "-Xintellij-plugin-root") {
1323			ctx.PropertyErrorf("kotlincflags",
1324				"Bad flag: `%s`, only use internal compiler for consistency.", flag)
1325		} else if inList(flag, config.KotlincIllegalFlags) {
1326			ctx.PropertyErrorf("kotlincflags", "Flag `%s` already used by build system", flag)
1327		} else if flag == "-include-runtime" {
1328			ctx.PropertyErrorf("kotlincflags", "Bad flag: `%s`, do not include runtime.", flag)
1329		} else {
1330			args := strings.Split(flag, " ")
1331			if args[0] == "-kotlin-home" {
1332				ctx.PropertyErrorf("kotlincflags",
1333					"Bad flag: `%s`, kotlin home already set to default (path to kotlinc in the repo).", flag)
1334			}
1335		}
1336	}
1337}
1338
1339func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
1340	deps deps, flags javaBuilderFlags, jarName string, extraJars android.Paths) android.Path {
1341
1342	var jars android.Paths
1343	if len(srcFiles) > 0 || len(srcJars) > 0 {
1344		// Compile java sources into turbine.jar.
1345		turbineJar := android.PathForModuleOut(ctx, "turbine", jarName)
1346		TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags)
1347		if ctx.Failed() {
1348			return nil
1349		}
1350		jars = append(jars, turbineJar)
1351	}
1352
1353	jars = append(jars, extraJars...)
1354
1355	// Combine any static header libraries into classes-header.jar. If there is only
1356	// one input jar this step will be skipped.
1357	var headerJar android.Path
1358	jars = append(jars, deps.staticHeaderJars...)
1359
1360	// we cannot skip the combine step for now if there is only one jar
1361	// since we have to strip META-INF/TRANSITIVE dir from turbine.jar
1362	combinedJar := android.PathForModuleOut(ctx, "turbine-combined", jarName)
1363	TransformJarsToJar(ctx, combinedJar, "for turbine", jars, android.OptionalPath{},
1364		false, nil, []string{"META-INF"})
1365	headerJar = combinedJar
1366
1367	if j.expandJarjarRules != nil {
1368		// Transform classes.jar into classes-jarjar.jar
1369		jarjarFile := android.PathForModuleOut(ctx, "turbine-jarjar", jarName)
1370		TransformJarJar(ctx, jarjarFile, headerJar, j.expandJarjarRules)
1371		headerJar = jarjarFile
1372		if ctx.Failed() {
1373			return nil
1374		}
1375	}
1376
1377	return headerJar
1378}
1379
1380func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
1381	classesJar android.Path, jarName string) android.ModuleOutPath {
1382
1383	specs := j.jacocoModuleToZipCommand(ctx)
1384
1385	jacocoReportClassesFile := android.PathForModuleOut(ctx, "jacoco-report-classes", jarName)
1386	instrumentedJar := android.PathForModuleOut(ctx, "jacoco", jarName)
1387
1388	jacocoInstrumentJar(ctx, instrumentedJar, jacocoReportClassesFile, classesJar, specs)
1389
1390	j.jacocoReportClassesFile = jacocoReportClassesFile
1391
1392	return instrumentedJar
1393}
1394
1395var _ Dependency = (*Module)(nil)
1396
1397func (j *Module) HeaderJars() android.Paths {
1398	if j.headerJarFile == nil {
1399		return nil
1400	}
1401	return android.Paths{j.headerJarFile}
1402}
1403
1404func (j *Module) ImplementationJars() android.Paths {
1405	if j.implementationJarFile == nil {
1406		return nil
1407	}
1408	return android.Paths{j.implementationJarFile}
1409}
1410
1411func (j *Module) DexJar() android.Path {
1412	return j.dexJarFile
1413}
1414
1415func (j *Module) ResourceJars() android.Paths {
1416	if j.resourceJar == nil {
1417		return nil
1418	}
1419	return android.Paths{j.resourceJar}
1420}
1421
1422func (j *Module) ImplementationAndResourcesJars() android.Paths {
1423	if j.implementationAndResourcesJar == nil {
1424		return nil
1425	}
1426	return android.Paths{j.implementationAndResourcesJar}
1427}
1428
1429func (j *Module) AidlIncludeDirs() android.Paths {
1430	// exportAidlIncludeDirs is type android.Paths already
1431	return j.exportAidlIncludeDirs
1432}
1433
1434func (j *Module) ExportedSdkLibs() []string {
1435	// exportedSdkLibs is type []string
1436	return j.exportedSdkLibs
1437}
1438
1439var _ logtagsProducer = (*Module)(nil)
1440
1441func (j *Module) logtags() android.Paths {
1442	return j.logtagsSrcs
1443}
1444
1445// Collect information for opening IDE project files in java/jdeps.go.
1446func (j *Module) IDEInfo(dpInfo *android.IdeInfo) {
1447	dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...)
1448	dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...)
1449	dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...)
1450	if j.expandJarjarRules != nil {
1451		dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
1452	}
1453}
1454
1455func (j *Module) CompilerDeps() []string {
1456	jdeps := []string{}
1457	jdeps = append(jdeps, j.properties.Libs...)
1458	jdeps = append(jdeps, j.properties.Static_libs...)
1459	return jdeps
1460}
1461
1462//
1463// Java libraries (.jar file)
1464//
1465
1466type Library struct {
1467	Module
1468}
1469
1470func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool {
1471	// Store uncompressed (and do not strip) dex files from boot class path jars.
1472	if inList(ctx.ModuleName(), ctx.Config().BootJars()) {
1473		return true
1474	}
1475
1476	// Store uncompressed dex files that are preopted on /system.
1477	if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, dexpreopter.installPath)) {
1478		return true
1479	}
1480	if ctx.Config().UncompressPrivAppDex() &&
1481		inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()) {
1482		return true
1483	}
1484
1485	return false
1486}
1487
1488func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1489	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", ctx.ModuleName()+".jar")
1490	j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
1491	j.dexpreopter.isInstallable = Bool(j.properties.Installable)
1492	j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
1493	j.deviceProperties.UncompressDex = j.dexpreopter.uncompressedDex
1494	j.compile(ctx)
1495
1496	if (Bool(j.properties.Installable) || ctx.Host()) && !android.DirectlyInAnyApex(ctx, ctx.ModuleName()) {
1497		j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
1498			ctx.ModuleName()+".jar", j.outputFile)
1499	}
1500}
1501
1502func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
1503	j.deps(ctx)
1504}
1505
1506// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well.
1507//
1508// By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were
1509// compiled against the device bootclasspath.  This jar is not suitable for installing on a device, but can be used
1510// as a `static_libs` dependency of another module.
1511//
1512// Specifying `installable: true` will product a `.jar` file containing `classes.dex` files, suitable for installing on
1513// a device.
1514//
1515// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
1516// compiled against the host bootclasspath.
1517func LibraryFactory() android.Module {
1518	module := &Library{}
1519
1520	module.AddProperties(
1521		&module.Module.properties,
1522		&module.Module.deviceProperties,
1523		&module.Module.dexpreoptProperties,
1524		&module.Module.protoProperties)
1525
1526	InitJavaModule(module, android.HostAndDeviceSupported)
1527	return module
1528}
1529
1530// java_library_static is an obsolete alias for java_library.
1531func LibraryStaticFactory() android.Module {
1532	return LibraryFactory()
1533}
1534
1535// java_library_host builds and links sources into a `.jar` file for the host.
1536//
1537// A java_library_host has a single variant that produces a `.jar` file containing `.class` files that were
1538// compiled against the host bootclasspath.
1539func LibraryHostFactory() android.Module {
1540	module := &Library{}
1541
1542	module.AddProperties(
1543		&module.Module.properties,
1544		&module.Module.protoProperties)
1545
1546	module.Module.properties.Installable = proptools.BoolPtr(true)
1547
1548	InitJavaModule(module, android.HostSupported)
1549	return module
1550}
1551
1552//
1553// Java Tests
1554//
1555
1556type testProperties struct {
1557	// list of compatibility suites (for example "cts", "vts") that the module should be
1558	// installed into.
1559	Test_suites []string `android:"arch_variant"`
1560
1561	// the name of the test configuration (for example "AndroidTest.xml") that should be
1562	// installed with the module.
1563	Test_config *string `android:"path,arch_variant"`
1564
1565	// the name of the test configuration template (for example "AndroidTestTemplate.xml") that
1566	// should be installed with the module.
1567	Test_config_template *string `android:"path,arch_variant"`
1568
1569	// list of files or filegroup modules that provide data that should be installed alongside
1570	// the test
1571	Data []string `android:"path"`
1572}
1573
1574type testHelperLibraryProperties struct {
1575	// list of compatibility suites (for example "cts", "vts") that the module should be
1576	// installed into.
1577	Test_suites []string `android:"arch_variant"`
1578}
1579
1580type Test struct {
1581	Library
1582
1583	testProperties testProperties
1584
1585	testConfig android.Path
1586	data       android.Paths
1587}
1588
1589type TestHelperLibrary struct {
1590	Library
1591
1592	testHelperLibraryProperties testHelperLibraryProperties
1593}
1594
1595func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1596	j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template, j.testProperties.Test_suites)
1597	j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
1598
1599	j.Library.GenerateAndroidBuildActions(ctx)
1600}
1601
1602func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1603	j.Library.GenerateAndroidBuildActions(ctx)
1604}
1605
1606// java_test builds a and links sources into a `.jar` file for the device, and possibly for the host as well, and
1607// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
1608//
1609// By default, a java_test has a single variant that produces a `.jar` file containing `classes.dex` files that were
1610// compiled against the device bootclasspath.
1611//
1612// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
1613// compiled against the host bootclasspath.
1614func TestFactory() android.Module {
1615	module := &Test{}
1616
1617	module.AddProperties(
1618		&module.Module.properties,
1619		&module.Module.deviceProperties,
1620		&module.Module.dexpreoptProperties,
1621		&module.Module.protoProperties,
1622		&module.testProperties)
1623
1624	module.Module.properties.Installable = proptools.BoolPtr(true)
1625	module.Module.dexpreopter.isTest = true
1626
1627	InitJavaModule(module, android.HostAndDeviceSupported)
1628	return module
1629}
1630
1631// java_test_helper_library creates a java library and makes sure that it is added to the appropriate test suite.
1632func TestHelperLibraryFactory() android.Module {
1633	module := &TestHelperLibrary{}
1634
1635	module.AddProperties(
1636		&module.Module.properties,
1637		&module.Module.deviceProperties,
1638		&module.Module.dexpreoptProperties,
1639		&module.Module.protoProperties,
1640		&module.testHelperLibraryProperties)
1641
1642	InitJavaModule(module, android.HostAndDeviceSupported)
1643	return module
1644}
1645
1646// java_test_host builds a and links sources into a `.jar` file for the host, and creates an `AndroidTest.xml` file to
1647// allow running the test with `atest` or a `TEST_MAPPING` file.
1648//
1649// A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were
1650// compiled against the host bootclasspath.
1651func TestHostFactory() android.Module {
1652	module := &Test{}
1653
1654	module.AddProperties(
1655		&module.Module.properties,
1656		&module.Module.protoProperties,
1657		&module.testProperties)
1658
1659	module.Module.properties.Installable = proptools.BoolPtr(true)
1660
1661	InitJavaModule(module, android.HostSupported)
1662	return module
1663}
1664
1665//
1666// Java Binaries (.jar file plus wrapper script)
1667//
1668
1669type binaryProperties struct {
1670	// installable script to execute the resulting jar
1671	Wrapper *string `android:"path"`
1672
1673	// Name of the class containing main to be inserted into the manifest as Main-Class.
1674	Main_class *string
1675}
1676
1677type Binary struct {
1678	Library
1679
1680	binaryProperties binaryProperties
1681
1682	isWrapperVariant bool
1683
1684	wrapperFile android.Path
1685	binaryFile  android.OutputPath
1686}
1687
1688func (j *Binary) HostToolPath() android.OptionalPath {
1689	return android.OptionalPathForPath(j.binaryFile)
1690}
1691
1692func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1693	if ctx.Arch().ArchType == android.Common {
1694		// Compile the jar
1695		if j.binaryProperties.Main_class != nil {
1696			if j.properties.Manifest != nil {
1697				ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set")
1698			}
1699			manifestFile := android.PathForModuleOut(ctx, "manifest.txt")
1700			GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class))
1701			j.overrideManifest = android.OptionalPathForPath(manifestFile)
1702		}
1703
1704		j.Library.GenerateAndroidBuildActions(ctx)
1705	} else {
1706		// Handle the binary wrapper
1707		j.isWrapperVariant = true
1708
1709		if j.binaryProperties.Wrapper != nil {
1710			j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper)
1711		} else {
1712			j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh")
1713		}
1714
1715		// Depend on the installed jar so that the wrapper doesn't get executed by
1716		// another build rule before the jar has been installed.
1717		jarFile := ctx.PrimaryModule().(*Binary).installFile
1718
1719		j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"),
1720			ctx.ModuleName(), j.wrapperFile, jarFile)
1721	}
1722}
1723
1724func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
1725	if ctx.Arch().ArchType == android.Common {
1726		j.deps(ctx)
1727	}
1728}
1729
1730// java_binary builds a `.jar` file and a shell script that executes it for the device, and possibly for the host
1731// as well.
1732//
1733// By default, a java_binary has a single variant that produces a `.jar` file containing `classes.dex` files that were
1734// compiled against the device bootclasspath.
1735//
1736// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
1737// compiled against the host bootclasspath.
1738func BinaryFactory() android.Module {
1739	module := &Binary{}
1740
1741	module.AddProperties(
1742		&module.Module.properties,
1743		&module.Module.deviceProperties,
1744		&module.Module.dexpreoptProperties,
1745		&module.Module.protoProperties,
1746		&module.binaryProperties)
1747
1748	module.Module.properties.Installable = proptools.BoolPtr(true)
1749
1750	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst)
1751	android.InitDefaultableModule(module)
1752	return module
1753}
1754
1755// java_binary_host builds a `.jar` file and a shell script that executes it for the host.
1756//
1757// A java_binary_host has a single variant that produces a `.jar` file containing `.class` files that were
1758// compiled against the host bootclasspath.
1759func BinaryHostFactory() android.Module {
1760	module := &Binary{}
1761
1762	module.AddProperties(
1763		&module.Module.properties,
1764		&module.Module.protoProperties,
1765		&module.binaryProperties)
1766
1767	module.Module.properties.Installable = proptools.BoolPtr(true)
1768
1769	android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst)
1770	android.InitDefaultableModule(module)
1771	return module
1772}
1773
1774//
1775// Java prebuilts
1776//
1777
1778type ImportProperties struct {
1779	Jars []string `android:"path"`
1780
1781	Sdk_version *string
1782
1783	Installable *bool
1784
1785	// List of shared java libs that this module has dependencies to
1786	Libs []string
1787
1788	// List of files to remove from the jar file(s)
1789	Exclude_files []string
1790
1791	// List of directories to remove from the jar file(s)
1792	Exclude_dirs []string
1793
1794	// if set to true, run Jetifier against .jar file. Defaults to false.
1795	Jetifier *bool
1796}
1797
1798type Import struct {
1799	android.ModuleBase
1800	android.DefaultableModuleBase
1801	prebuilt android.Prebuilt
1802
1803	properties ImportProperties
1804
1805	combinedClasspathFile android.Path
1806	exportedSdkLibs       []string
1807}
1808
1809func (j *Import) sdkVersion() string {
1810	return String(j.properties.Sdk_version)
1811}
1812
1813func (j *Import) minSdkVersion() string {
1814	return j.sdkVersion()
1815}
1816
1817func (j *Import) Prebuilt() *android.Prebuilt {
1818	return &j.prebuilt
1819}
1820
1821func (j *Import) PrebuiltSrcs() []string {
1822	return j.properties.Jars
1823}
1824
1825func (j *Import) Name() string {
1826	return j.prebuilt.Name(j.ModuleBase.Name())
1827}
1828
1829func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
1830	ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
1831}
1832
1833func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1834	jars := android.PathsForModuleSrc(ctx, j.properties.Jars)
1835
1836	jarName := ctx.ModuleName() + ".jar"
1837	outputFile := android.PathForModuleOut(ctx, "combined", jarName)
1838	TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{},
1839		false, j.properties.Exclude_files, j.properties.Exclude_dirs)
1840	if Bool(j.properties.Jetifier) {
1841		inputFile := outputFile
1842		outputFile = android.PathForModuleOut(ctx, "jetifier", jarName)
1843		TransformJetifier(ctx, outputFile, inputFile)
1844	}
1845	j.combinedClasspathFile = outputFile
1846
1847	ctx.VisitDirectDeps(func(module android.Module) {
1848		otherName := ctx.OtherModuleName(module)
1849		tag := ctx.OtherModuleDependencyTag(module)
1850
1851		switch dep := module.(type) {
1852		case Dependency:
1853			switch tag {
1854			case libTag, staticLibTag:
1855				// sdk lib names from dependencies are re-exported
1856				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
1857			}
1858		case SdkLibraryDependency:
1859			switch tag {
1860			case libTag:
1861				// names of sdk libs that are directly depended are exported
1862				j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
1863			}
1864		}
1865	})
1866
1867	j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)
1868	if Bool(j.properties.Installable) {
1869		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
1870			ctx.ModuleName()+".jar", outputFile)
1871	}
1872}
1873
1874var _ Dependency = (*Import)(nil)
1875
1876func (j *Import) HeaderJars() android.Paths {
1877	if j.combinedClasspathFile == nil {
1878		return nil
1879	}
1880	return android.Paths{j.combinedClasspathFile}
1881}
1882
1883func (j *Import) ImplementationJars() android.Paths {
1884	if j.combinedClasspathFile == nil {
1885		return nil
1886	}
1887	return android.Paths{j.combinedClasspathFile}
1888}
1889
1890func (j *Import) ResourceJars() android.Paths {
1891	return nil
1892}
1893
1894func (j *Import) ImplementationAndResourcesJars() android.Paths {
1895	if j.combinedClasspathFile == nil {
1896		return nil
1897	}
1898	return android.Paths{j.combinedClasspathFile}
1899}
1900
1901func (j *Import) DexJar() android.Path {
1902	return nil
1903}
1904
1905func (j *Import) AidlIncludeDirs() android.Paths {
1906	return nil
1907}
1908
1909func (j *Import) ExportedSdkLibs() []string {
1910	return j.exportedSdkLibs
1911}
1912
1913// Add compile time check for interface implementation
1914var _ android.IDEInfo = (*Import)(nil)
1915var _ android.IDECustomizedModuleName = (*Import)(nil)
1916
1917// Collect information for opening IDE project files in java/jdeps.go.
1918const (
1919	removedPrefix = "prebuilt_"
1920)
1921
1922func (j *Import) IDEInfo(dpInfo *android.IdeInfo) {
1923	dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...)
1924}
1925
1926func (j *Import) IDECustomizedModuleName() string {
1927	// TODO(b/113562217): Extract the base module name from the Import name, often the Import name
1928	// has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better
1929	// solution to get the Import name.
1930	name := j.Name()
1931	if strings.HasPrefix(name, removedPrefix) {
1932		name = strings.TrimPrefix(name, removedPrefix)
1933	}
1934	return name
1935}
1936
1937var _ android.PrebuiltInterface = (*Import)(nil)
1938
1939// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module.
1940//
1941// By default, a java_import has a single variant that expects a `.jar` file containing `.class` files that were
1942// compiled against an Android classpath.
1943//
1944// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
1945// for host modules.
1946func ImportFactory() android.Module {
1947	module := &Import{}
1948
1949	module.AddProperties(&module.properties)
1950
1951	android.InitPrebuiltModule(module, &module.properties.Jars)
1952	InitJavaModule(module, android.HostAndDeviceSupported)
1953	return module
1954}
1955
1956// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library_host
1957// module.
1958//
1959// A java_import_host has a single variant that expects a `.jar` file containing `.class` files that were
1960// compiled against a host bootclasspath.
1961func ImportFactoryHost() android.Module {
1962	module := &Import{}
1963
1964	module.AddProperties(&module.properties)
1965
1966	android.InitPrebuiltModule(module, &module.properties.Jars)
1967	InitJavaModule(module, android.HostSupported)
1968	return module
1969}
1970
1971// dex_import module
1972
1973type DexImportProperties struct {
1974	Jars []string
1975}
1976
1977type DexImport struct {
1978	android.ModuleBase
1979	android.DefaultableModuleBase
1980	prebuilt android.Prebuilt
1981
1982	properties DexImportProperties
1983
1984	dexJarFile              android.Path
1985	maybeStrippedDexJarFile android.Path
1986
1987	dexpreopter
1988}
1989
1990func (j *DexImport) Prebuilt() *android.Prebuilt {
1991	return &j.prebuilt
1992}
1993
1994func (j *DexImport) PrebuiltSrcs() []string {
1995	return j.properties.Jars
1996}
1997
1998func (j *DexImport) Name() string {
1999	return j.prebuilt.Name(j.ModuleBase.Name())
2000}
2001
2002func (j *DexImport) DepsMutator(ctx android.BottomUpMutatorContext) {
2003	android.ExtractSourcesDeps(ctx, j.properties.Jars)
2004}
2005
2006func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2007	if len(j.properties.Jars) != 1 {
2008		ctx.PropertyErrorf("jars", "exactly one jar must be provided")
2009	}
2010
2011	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", ctx.ModuleName()+".jar")
2012	j.dexpreopter.isInstallable = true
2013	j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
2014
2015	inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars")
2016	dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar")
2017
2018	if j.dexpreopter.uncompressedDex {
2019		rule := android.NewRuleBuilder()
2020
2021		temporary := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar.unaligned")
2022		rule.Temporary(temporary)
2023
2024		// use zip2zip to uncompress classes*.dex files
2025		rule.Command().
2026			Tool(ctx.Config().HostToolPath(ctx, "zip2zip")).
2027			FlagWithInput("-i ", inputJar).
2028			FlagWithOutput("-o ", temporary).
2029			FlagWithArg("-0 ", "'classes*.dex'")
2030
2031		// use zipalign to align uncompressed classes*.dex files
2032		rule.Command().
2033			Tool(ctx.Config().HostToolPath(ctx, "zipalign")).
2034			Flag("-f").
2035			Text("4").
2036			Input(temporary).
2037			Output(dexOutputFile)
2038
2039		rule.DeleteTemporaryFiles()
2040
2041		rule.Build(pctx, ctx, "uncompress_dex", "uncompress dex")
2042	} else {
2043		ctx.Build(pctx, android.BuildParams{
2044			Rule:   android.Cp,
2045			Input:  inputJar,
2046			Output: dexOutputFile,
2047		})
2048	}
2049
2050	j.dexJarFile = dexOutputFile
2051
2052	dexOutputFile = j.dexpreopt(ctx, dexOutputFile)
2053
2054	j.maybeStrippedDexJarFile = dexOutputFile
2055
2056	ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
2057		ctx.ModuleName()+".jar", dexOutputFile)
2058}
2059
2060func (j *DexImport) DexJar() android.Path {
2061	return j.dexJarFile
2062}
2063
2064// dex_import imports a `.jar` file containing classes.dex files.
2065//
2066// A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed
2067// to the device.
2068func DexImportFactory() android.Module {
2069	module := &DexImport{}
2070
2071	module.AddProperties(&module.properties)
2072
2073	android.InitPrebuiltModule(module, &module.properties.Jars)
2074	InitJavaModule(module, android.DeviceSupported)
2075	return module
2076}
2077
2078//
2079// Defaults
2080//
2081type Defaults struct {
2082	android.ModuleBase
2083	android.DefaultsModuleBase
2084}
2085
2086func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
2087}
2088
2089// java_defaults provides a set of properties that can be inherited by other java or android modules.
2090//
2091// A module can use the properties from a java_defaults module using `defaults: ["defaults_module_name"]`.  Each
2092// property in the defaults module that exists in the depending module will be prepended to the depending module's
2093// value for that property.
2094//
2095// Example:
2096//
2097//     java_defaults {
2098//         name: "example_defaults",
2099//         srcs: ["common/**/*.java"],
2100//         javacflags: ["-Xlint:all"],
2101//         aaptflags: ["--auto-add-overlay"],
2102//     }
2103//
2104//     java_library {
2105//         name: "example",
2106//         defaults: ["example_defaults"],
2107//         srcs: ["example/**/*.java"],
2108//     }
2109//
2110// is functionally identical to:
2111//
2112//     java_library {
2113//         name: "example",
2114//         srcs: [
2115//             "common/**/*.java",
2116//             "example/**/*.java",
2117//         ],
2118//         javacflags: ["-Xlint:all"],
2119//     }
2120func defaultsFactory() android.Module {
2121	return DefaultsFactory()
2122}
2123
2124func DefaultsFactory(props ...interface{}) android.Module {
2125	module := &Defaults{}
2126
2127	module.AddProperties(props...)
2128	module.AddProperties(
2129		&CompilerProperties{},
2130		&CompilerDeviceProperties{},
2131		&DexpreoptProperties{},
2132		&android.ProtoProperties{},
2133		&aaptProperties{},
2134		&androidLibraryProperties{},
2135		&appProperties{},
2136		&appTestProperties{},
2137		&overridableAppProperties{},
2138		&ImportProperties{},
2139		&AARImportProperties{},
2140		&sdkLibraryProperties{},
2141		&DexImportProperties{},
2142	)
2143
2144	android.InitDefaultsModule(module)
2145
2146	return module
2147}
2148
2149var Bool = proptools.Bool
2150var BoolDefault = proptools.BoolDefault
2151var String = proptools.String
2152var inList = android.InList
2153