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	"strings"
25
26	"github.com/google/blueprint"
27	"github.com/google/blueprint/proptools"
28
29	"android/soong/android"
30	"android/soong/cc"
31	"android/soong/dexpreopt"
32	"android/soong/java/config"
33	"android/soong/tradefed"
34)
35
36func init() {
37	registerJavaBuildComponents(android.InitRegistrationContext)
38
39	RegisterJavaSdkMemberTypes()
40}
41
42func registerJavaBuildComponents(ctx android.RegistrationContext) {
43	ctx.RegisterModuleType("java_defaults", DefaultsFactory)
44
45	ctx.RegisterModuleType("java_library", LibraryFactory)
46	ctx.RegisterModuleType("java_library_static", LibraryStaticFactory)
47	ctx.RegisterModuleType("java_library_host", LibraryHostFactory)
48	ctx.RegisterModuleType("java_binary", BinaryFactory)
49	ctx.RegisterModuleType("java_binary_host", BinaryHostFactory)
50	ctx.RegisterModuleType("java_test", TestFactory)
51	ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory)
52	ctx.RegisterModuleType("java_test_host", TestHostFactory)
53	ctx.RegisterModuleType("java_test_import", JavaTestImportFactory)
54	ctx.RegisterModuleType("java_import", ImportFactory)
55	ctx.RegisterModuleType("java_import_host", ImportFactoryHost)
56	ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory)
57	ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
58	ctx.RegisterModuleType("dex_import", DexImportFactory)
59
60	// This mutator registers dependencies on dex2oat for modules that should be
61	// dexpreopted. This is done late when the final variants have been
62	// established, to not get the dependencies split into the wrong variants and
63	// to support the checks in dexpreoptDisabled().
64	ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
65		ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel()
66	})
67
68	ctx.RegisterSingletonType("logtags", LogtagsSingleton)
69	ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
70}
71
72func RegisterJavaSdkMemberTypes() {
73	// Register sdk member types.
74	android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType)
75	android.RegisterSdkMemberType(javaLibsSdkMemberType)
76	android.RegisterSdkMemberType(javaBootLibsSdkMemberType)
77	android.RegisterSdkMemberType(javaTestSdkMemberType)
78}
79
80var (
81	// Supports adding java header libraries to module_exports and sdk.
82	javaHeaderLibsSdkMemberType = &librarySdkMemberType{
83		android.SdkMemberTypeBase{
84			PropertyName: "java_header_libs",
85			SupportsSdk:  true,
86		},
87		func(_ android.SdkMemberContext, j *Library) android.Path {
88			headerJars := j.HeaderJars()
89			if len(headerJars) != 1 {
90				panic(fmt.Errorf("there must be only one header jar from %q", j.Name()))
91			}
92
93			return headerJars[0]
94		},
95		sdkSnapshotFilePathForJar,
96		copyEverythingToSnapshot,
97	}
98
99	// Export implementation classes jar as part of the sdk.
100	exportImplementationClassesJar = func(_ android.SdkMemberContext, j *Library) android.Path {
101		implementationJars := j.ImplementationAndResourcesJars()
102		if len(implementationJars) != 1 {
103			panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name()))
104		}
105		return implementationJars[0]
106	}
107
108	// Supports adding java implementation libraries to module_exports but not sdk.
109	javaLibsSdkMemberType = &librarySdkMemberType{
110		android.SdkMemberTypeBase{
111			PropertyName: "java_libs",
112		},
113		exportImplementationClassesJar,
114		sdkSnapshotFilePathForJar,
115		copyEverythingToSnapshot,
116	}
117
118	// Supports adding java boot libraries to module_exports and sdk.
119	//
120	// The build has some implicit dependencies (via the boot jars configuration) on a number of
121	// modules, e.g. core-oj, apache-xml, that are part of the java boot class path and which are
122	// provided by mainline modules (e.g. art, conscrypt, runtime-i18n) but which are not otherwise
123	// used outside those mainline modules.
124	//
125	// As they are not needed outside the mainline modules adding them to the sdk/module-exports as
126	// either java_libs, or java_header_libs would end up exporting more information than was strictly
127	// necessary. The java_boot_libs property to allow those modules to be exported as part of the
128	// sdk/module_exports without exposing any unnecessary information.
129	javaBootLibsSdkMemberType = &librarySdkMemberType{
130		android.SdkMemberTypeBase{
131			PropertyName: "java_boot_libs",
132			SupportsSdk:  true,
133		},
134		// Temporarily export implementation classes jar for java_boot_libs as it is required for the
135		// hiddenapi processing.
136		// TODO(b/179354495): Revert once hiddenapi processing has been modularized.
137		exportImplementationClassesJar,
138		sdkSnapshotFilePathForJar,
139		onlyCopyJarToSnapshot,
140	}
141
142	// Supports adding java test libraries to module_exports but not sdk.
143	javaTestSdkMemberType = &testSdkMemberType{
144		SdkMemberTypeBase: android.SdkMemberTypeBase{
145			PropertyName: "java_tests",
146		},
147	}
148)
149
150// JavaInfo contains information about a java module for use by modules that depend on it.
151type JavaInfo struct {
152	// HeaderJars is a list of jars that can be passed as the javac classpath in order to link
153	// against this module.  If empty, ImplementationJars should be used instead.
154	HeaderJars android.Paths
155
156	// ImplementationAndResourceJars is a list of jars that contain the implementations of classes
157	// in the module as well as any resources included in the module.
158	ImplementationAndResourcesJars android.Paths
159
160	// ImplementationJars is a list of jars that contain the implementations of classes in the
161	//module.
162	ImplementationJars android.Paths
163
164	// ResourceJars is a list of jars that contain the resources included in the module.
165	ResourceJars android.Paths
166
167	// AidlIncludeDirs is a list of directories that should be passed to the aidl tool when
168	// depending on this module.
169	AidlIncludeDirs android.Paths
170
171	// SrcJarArgs is a list of arguments to pass to soong_zip to package the sources of this
172	// module.
173	SrcJarArgs []string
174
175	// SrcJarDeps is a list of paths to depend on when packaging the sources of this module.
176	SrcJarDeps android.Paths
177
178	// ExportedPlugins is a list of paths that should be used as annotation processors for any
179	// module that depends on this module.
180	ExportedPlugins android.Paths
181
182	// ExportedPluginClasses is a list of classes that should be run as annotation processors for
183	// any module that depends on this module.
184	ExportedPluginClasses []string
185
186	// ExportedPluginDisableTurbine is true if this module's annotation processors generate APIs,
187	// requiring disbling turbine for any modules that depend on it.
188	ExportedPluginDisableTurbine bool
189
190	// JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be
191	// instrumented by jacoco.
192	JacocoReportClassesFile android.Path
193}
194
195var JavaInfoProvider = blueprint.NewProvider(JavaInfo{})
196
197// SyspropPublicStubInfo contains info about the sysprop public stub library that corresponds to
198// the sysprop implementation library.
199type SyspropPublicStubInfo struct {
200	// JavaInfo is the JavaInfoProvider of the sysprop public stub library that corresponds to
201	// the sysprop implementation library.
202	JavaInfo JavaInfo
203}
204
205var SyspropPublicStubInfoProvider = blueprint.NewProvider(SyspropPublicStubInfo{})
206
207// Methods that need to be implemented for a module that is added to apex java_libs property.
208type ApexDependency interface {
209	HeaderJars() android.Paths
210	ImplementationAndResourcesJars() android.Paths
211}
212
213// Provides build path and install path to DEX jars.
214type UsesLibraryDependency interface {
215	DexJarBuildPath() android.Path
216	DexJarInstallPath() android.Path
217	ClassLoaderContexts() dexpreopt.ClassLoaderContextMap
218}
219
220// TODO(jungjw): Move this to kythe.go once it's created.
221type xref interface {
222	XrefJavaFiles() android.Paths
223}
224
225func (j *Module) XrefJavaFiles() android.Paths {
226	return j.kytheFiles
227}
228
229type dependencyTag struct {
230	blueprint.BaseDependencyTag
231	name string
232}
233
234// installDependencyTag is a dependency tag that is annotated to cause the installed files of the
235// dependency to be installed when the parent module is installed.
236type installDependencyTag struct {
237	blueprint.BaseDependencyTag
238	android.InstallAlwaysNeededDependencyTag
239	name string
240}
241
242type usesLibraryDependencyTag struct {
243	dependencyTag
244	sdkVersion int // SDK version in which the library appared as a standalone library.
245}
246
247func makeUsesLibraryDependencyTag(sdkVersion int) usesLibraryDependencyTag {
248	return usesLibraryDependencyTag{
249		dependencyTag: dependencyTag{name: fmt.Sprintf("uses-library-%d", sdkVersion)},
250		sdkVersion:    sdkVersion,
251	}
252}
253
254func IsJniDepTag(depTag blueprint.DependencyTag) bool {
255	return depTag == jniLibTag
256}
257
258var (
259	dataNativeBinsTag       = dependencyTag{name: "dataNativeBins"}
260	staticLibTag            = dependencyTag{name: "staticlib"}
261	libTag                  = dependencyTag{name: "javalib"}
262	java9LibTag             = dependencyTag{name: "java9lib"}
263	pluginTag               = dependencyTag{name: "plugin"}
264	errorpronePluginTag     = dependencyTag{name: "errorprone-plugin"}
265	exportedPluginTag       = dependencyTag{name: "exported-plugin"}
266	bootClasspathTag        = dependencyTag{name: "bootclasspath"}
267	systemModulesTag        = dependencyTag{name: "system modules"}
268	frameworkResTag         = dependencyTag{name: "framework-res"}
269	kotlinStdlibTag         = dependencyTag{name: "kotlin-stdlib"}
270	kotlinAnnotationsTag    = dependencyTag{name: "kotlin-annotations"}
271	proguardRaiseTag        = dependencyTag{name: "proguard-raise"}
272	certificateTag          = dependencyTag{name: "certificate"}
273	instrumentationForTag   = dependencyTag{name: "instrumentation_for"}
274	extraLintCheckTag       = dependencyTag{name: "extra-lint-check"}
275	jniLibTag               = dependencyTag{name: "jnilib"}
276	syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
277	jniInstallTag           = installDependencyTag{name: "jni install"}
278	binaryInstallTag        = installDependencyTag{name: "binary install"}
279	usesLibTag              = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion)
280	usesLibCompat28Tag      = makeUsesLibraryDependencyTag(28)
281	usesLibCompat29Tag      = makeUsesLibraryDependencyTag(29)
282	usesLibCompat30Tag      = makeUsesLibraryDependencyTag(30)
283)
284
285func IsLibDepTag(depTag blueprint.DependencyTag) bool {
286	return depTag == libTag
287}
288
289func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool {
290	return depTag == staticLibTag
291}
292
293type sdkDep struct {
294	useModule, useFiles, invalidVersion bool
295
296	// The modules that will be added to the bootclasspath when targeting 1.8 or lower
297	bootclasspath []string
298
299	// The default system modules to use. Will be an empty string if no system
300	// modules are to be used.
301	systemModules string
302
303	// The modules that will be added to the classpath regardless of the Java language level targeted
304	classpath []string
305
306	// The modules that will be added ot the classpath when targeting 1.9 or higher
307	// (normally these will be on the bootclasspath when targeting 1.8 or lower)
308	java9Classpath []string
309
310	frameworkResModule string
311
312	jars android.Paths
313	aidl android.OptionalPath
314
315	noStandardLibs, noFrameworksLibs bool
316}
317
318func (s sdkDep) hasStandardLibs() bool {
319	return !s.noStandardLibs
320}
321
322func (s sdkDep) hasFrameworkLibs() bool {
323	return !s.noStandardLibs && !s.noFrameworksLibs
324}
325
326type jniLib struct {
327	name           string
328	path           android.Path
329	target         android.Target
330	coverageFile   android.OptionalPath
331	unstrippedFile android.Path
332}
333
334func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) {
335	sdkDep := decodeSdkDep(ctx, sdkContext)
336	if sdkDep.useModule {
337		ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
338		ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
339		ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...)
340		if d.effectiveOptimizeEnabled() && sdkDep.hasStandardLibs() {
341			ctx.AddVariationDependencies(nil, proguardRaiseTag, config.LegacyCorePlatformBootclasspathLibraries...)
342		}
343		if d.effectiveOptimizeEnabled() && sdkDep.hasFrameworkLibs() {
344			ctx.AddVariationDependencies(nil, proguardRaiseTag, config.FrameworkLibraries...)
345		}
346	}
347	if sdkDep.systemModules != "" {
348		ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
349	}
350}
351
352type deps struct {
353	classpath               classpath
354	java9Classpath          classpath
355	bootClasspath           classpath
356	processorPath           classpath
357	errorProneProcessorPath classpath
358	processorClasses        []string
359	staticJars              android.Paths
360	staticHeaderJars        android.Paths
361	staticResourceJars      android.Paths
362	aidlIncludeDirs         android.Paths
363	srcs                    android.Paths
364	srcJars                 android.Paths
365	systemModules           *systemModules
366	aidlPreprocess          android.OptionalPath
367	kotlinStdlib            android.Paths
368	kotlinAnnotations       android.Paths
369
370	disableTurbine bool
371}
372
373func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) {
374	for _, f := range dep.Srcs() {
375		if f.Ext() != ".jar" {
376			ctx.ModuleErrorf("genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency",
377				ctx.OtherModuleName(dep.(blueprint.Module)))
378		}
379	}
380}
381
382func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext android.SdkContext) javaVersion {
383	if javaVersion != "" {
384		return normalizeJavaVersion(ctx, javaVersion)
385	} else if ctx.Device() {
386		return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx))
387	} else {
388		return JAVA_VERSION_9
389	}
390}
391
392type javaVersion int
393
394const (
395	JAVA_VERSION_UNSUPPORTED = 0
396	JAVA_VERSION_6           = 6
397	JAVA_VERSION_7           = 7
398	JAVA_VERSION_8           = 8
399	JAVA_VERSION_9           = 9
400)
401
402func (v javaVersion) String() string {
403	switch v {
404	case JAVA_VERSION_6:
405		return "1.6"
406	case JAVA_VERSION_7:
407		return "1.7"
408	case JAVA_VERSION_8:
409		return "1.8"
410	case JAVA_VERSION_9:
411		return "1.9"
412	default:
413		return "unsupported"
414	}
415}
416
417// Returns true if javac targeting this version uses system modules instead of a bootclasspath.
418func (v javaVersion) usesJavaModules() bool {
419	return v >= 9
420}
421
422func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) javaVersion {
423	switch javaVersion {
424	case "1.6", "6":
425		return JAVA_VERSION_6
426	case "1.7", "7":
427		return JAVA_VERSION_7
428	case "1.8", "8":
429		return JAVA_VERSION_8
430	case "1.9", "9":
431		return JAVA_VERSION_9
432	case "10", "11":
433		ctx.PropertyErrorf("java_version", "Java language levels above 9 are not supported")
434		return JAVA_VERSION_UNSUPPORTED
435	default:
436		ctx.PropertyErrorf("java_version", "Unrecognized Java language level")
437		return JAVA_VERSION_UNSUPPORTED
438	}
439}
440
441//
442// Java libraries (.jar file)
443//
444
445type Library struct {
446	Module
447
448	InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths)
449}
450
451var _ android.ApexModule = (*Library)(nil)
452
453// Provides access to the list of permitted packages from updatable boot jars.
454type PermittedPackagesForUpdatableBootJars interface {
455	PermittedPackagesForUpdatableBootJars() []string
456}
457
458var _ PermittedPackagesForUpdatableBootJars = (*Library)(nil)
459
460func (j *Library) PermittedPackagesForUpdatableBootJars() []string {
461	return j.properties.Permitted_packages
462}
463
464func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool {
465	// Store uncompressed (and aligned) any dex files from jars in APEXes.
466	if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() {
467		return true
468	}
469
470	// Store uncompressed (and do not strip) dex files from boot class path jars.
471	if inList(ctx.ModuleName(), ctx.Config().BootJars()) {
472		return true
473	}
474
475	// Store uncompressed dex files that are preopted on /system.
476	if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, dexpreopter.installPath)) {
477		return true
478	}
479	if ctx.Config().UncompressPrivAppDex() &&
480		inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()) {
481		return true
482	}
483
484	return false
485}
486
487func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
488	j.sdkVersion = j.SdkVersion(ctx)
489	j.minSdkVersion = j.MinSdkVersion(ctx)
490
491	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
492	if !apexInfo.IsForPlatform() {
493		j.hideApexVariantFromMake = true
494	}
495
496	j.checkSdkVersions(ctx)
497	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
498	j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
499	if j.dexProperties.Uncompress_dex == nil {
500		// If the value was not force-set by the user, use reasonable default based on the module.
501		j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
502	}
503	j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
504	j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
505	j.compile(ctx, nil)
506
507	// Collect the module directory for IDE info in java/jdeps.go.
508	j.modulePaths = append(j.modulePaths, ctx.ModuleDir())
509
510	exclusivelyForApex := !apexInfo.IsForPlatform()
511	if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex {
512		var extraInstallDeps android.Paths
513		if j.InstallMixin != nil {
514			extraInstallDeps = j.InstallMixin(ctx, j.outputFile)
515		}
516		j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
517			j.Stem()+".jar", j.outputFile, extraInstallDeps...)
518	}
519}
520
521func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
522	j.deps(ctx)
523}
524
525const (
526	aidlIncludeDir   = "aidl"
527	javaDir          = "java"
528	jarFileSuffix    = ".jar"
529	testConfigSuffix = "-AndroidTest.xml"
530)
531
532// path to the jar file of a java library. Relative to <sdk_root>/<api_dir>
533func sdkSnapshotFilePathForJar(osPrefix, name string) string {
534	return sdkSnapshotFilePathForMember(osPrefix, name, jarFileSuffix)
535}
536
537func sdkSnapshotFilePathForMember(osPrefix, name string, suffix string) string {
538	return filepath.Join(javaDir, osPrefix, name+suffix)
539}
540
541type librarySdkMemberType struct {
542	android.SdkMemberTypeBase
543
544	// Function to retrieve the appropriate output jar (implementation or header) from
545	// the library.
546	jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path
547
548	// Function to compute the snapshot relative path to which the named library's
549	// jar should be copied.
550	snapshotPathGetter func(osPrefix, name string) string
551
552	// True if only the jar should be copied to the snapshot, false if the jar plus any additional
553	// files like aidl files should also be copied.
554	onlyCopyJarToSnapshot bool
555}
556
557const (
558	onlyCopyJarToSnapshot    = true
559	copyEverythingToSnapshot = false
560)
561
562func (mt *librarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
563	mctx.AddVariationDependencies(nil, dependencyTag, names...)
564}
565
566func (mt *librarySdkMemberType) IsInstance(module android.Module) bool {
567	_, ok := module.(*Library)
568	return ok
569}
570
571func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
572	return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_import")
573}
574
575func (mt *librarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
576	return &librarySdkMemberProperties{}
577}
578
579type librarySdkMemberProperties struct {
580	android.SdkMemberPropertiesBase
581
582	JarToExport     android.Path `android:"arch_variant"`
583	AidlIncludeDirs android.Paths
584
585	// The list of permitted packages that need to be passed to the prebuilts as they are used to
586	// create the updatable-bcp-packages.txt file.
587	PermittedPackages []string
588}
589
590func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
591	j := variant.(*Library)
592
593	p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j)
594
595	p.AidlIncludeDirs = j.AidlIncludeDirs()
596
597	p.PermittedPackages = j.PermittedPackagesForUpdatableBootJars()
598}
599
600func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
601	builder := ctx.SnapshotBuilder()
602
603	memberType := ctx.MemberType().(*librarySdkMemberType)
604
605	exportedJar := p.JarToExport
606	if exportedJar != nil {
607		// Delegate the creation of the snapshot relative path to the member type.
608		snapshotRelativeJavaLibPath := memberType.snapshotPathGetter(p.OsPrefix(), ctx.Name())
609
610		// Copy the exported jar to the snapshot.
611		builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath)
612
613		propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
614	}
615
616	if len(p.PermittedPackages) > 0 {
617		propertySet.AddProperty("permitted_packages", p.PermittedPackages)
618	}
619
620	// Do not copy anything else to the snapshot.
621	if memberType.onlyCopyJarToSnapshot {
622		return
623	}
624
625	aidlIncludeDirs := p.AidlIncludeDirs
626	if len(aidlIncludeDirs) != 0 {
627		sdkModuleContext := ctx.SdkModuleContext()
628		for _, dir := range aidlIncludeDirs {
629			// TODO(jiyong): copy parcelable declarations only
630			aidlFiles, _ := sdkModuleContext.GlobWithDeps(dir.String()+"/**/*.aidl", nil)
631			for _, file := range aidlFiles {
632				builder.CopyToSnapshot(android.PathForSource(sdkModuleContext, file), filepath.Join(aidlIncludeDir, file))
633			}
634		}
635
636		// TODO(b/151933053) - add aidl include dirs property
637	}
638}
639
640// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well.
641//
642// By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were
643// compiled against the device bootclasspath.  This jar is not suitable for installing on a device, but can be used
644// as a `static_libs` dependency of another module.
645//
646// Specifying `installable: true` will product a `.jar` file containing `classes.dex` files, suitable for installing on
647// a device.
648//
649// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
650// compiled against the host bootclasspath.
651func LibraryFactory() android.Module {
652	module := &Library{}
653
654	module.addHostAndDeviceProperties()
655
656	module.initModuleAndImport(module)
657
658	android.InitApexModule(module)
659	android.InitSdkAwareModule(module)
660	InitJavaModule(module, android.HostAndDeviceSupported)
661	return module
662}
663
664// java_library_static is an obsolete alias for java_library.
665func LibraryStaticFactory() android.Module {
666	return LibraryFactory()
667}
668
669// java_library_host builds and links sources into a `.jar` file for the host.
670//
671// A java_library_host has a single variant that produces a `.jar` file containing `.class` files that were
672// compiled against the host bootclasspath.
673func LibraryHostFactory() android.Module {
674	module := &Library{}
675
676	module.addHostProperties()
677
678	module.Module.properties.Installable = proptools.BoolPtr(true)
679
680	android.InitApexModule(module)
681	android.InitSdkAwareModule(module)
682	InitJavaModule(module, android.HostSupported)
683	return module
684}
685
686//
687// Java Tests
688//
689
690// Test option struct.
691type TestOptions struct {
692	// a list of extra test configuration files that should be installed with the module.
693	Extra_test_configs []string `android:"path,arch_variant"`
694
695	// If the test is a hostside(no device required) unittest that shall be run during presubmit check.
696	Unit_test *bool
697}
698
699type testProperties struct {
700	// list of compatibility suites (for example "cts", "vts") that the module should be
701	// installed into.
702	Test_suites []string `android:"arch_variant"`
703
704	// the name of the test configuration (for example "AndroidTest.xml") that should be
705	// installed with the module.
706	Test_config *string `android:"path,arch_variant"`
707
708	// the name of the test configuration template (for example "AndroidTestTemplate.xml") that
709	// should be installed with the module.
710	Test_config_template *string `android:"path,arch_variant"`
711
712	// list of files or filegroup modules that provide data that should be installed alongside
713	// the test
714	Data []string `android:"path"`
715
716	// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
717	// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
718	// explicitly.
719	Auto_gen_config *bool
720
721	// Add parameterized mainline modules to auto generated test config. The options will be
722	// handled by TradeFed to do downloading and installing the specified modules on the device.
723	Test_mainline_modules []string
724
725	// Test options.
726	Test_options TestOptions
727
728	// Names of modules containing JNI libraries that should be installed alongside the test.
729	Jni_libs []string
730}
731
732type hostTestProperties struct {
733	// list of native binary modules that should be installed alongside the test
734	Data_native_bins []string `android:"arch_variant"`
735}
736
737type testHelperLibraryProperties struct {
738	// list of compatibility suites (for example "cts", "vts") that the module should be
739	// installed into.
740	Test_suites []string `android:"arch_variant"`
741}
742
743type prebuiltTestProperties struct {
744	// list of compatibility suites (for example "cts", "vts") that the module should be
745	// installed into.
746	Test_suites []string `android:"arch_variant"`
747
748	// the name of the test configuration (for example "AndroidTest.xml") that should be
749	// installed with the module.
750	Test_config *string `android:"path,arch_variant"`
751}
752
753type Test struct {
754	Library
755
756	testProperties testProperties
757
758	testConfig       android.Path
759	extraTestConfigs android.Paths
760	data             android.Paths
761}
762
763type TestHost struct {
764	Test
765
766	testHostProperties hostTestProperties
767}
768
769type TestHelperLibrary struct {
770	Library
771
772	testHelperLibraryProperties testHelperLibraryProperties
773}
774
775type JavaTestImport struct {
776	Import
777
778	prebuiltTestProperties prebuiltTestProperties
779
780	testConfig android.Path
781	dexJarFile android.Path
782}
783
784func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) {
785	if len(j.testHostProperties.Data_native_bins) > 0 {
786		for _, target := range ctx.MultiTargets() {
787			ctx.AddVariationDependencies(target.Variations(), dataNativeBinsTag, j.testHostProperties.Data_native_bins...)
788		}
789	}
790
791	if len(j.testProperties.Jni_libs) > 0 {
792		for _, target := range ctx.MultiTargets() {
793			sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
794			ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, j.testProperties.Jni_libs...)
795		}
796	}
797
798	j.deps(ctx)
799}
800
801func (j *TestHost) AddExtraResource(p android.Path) {
802	j.extraResources = append(j.extraResources, p)
803}
804
805func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
806	if j.testProperties.Test_options.Unit_test == nil && ctx.Host() {
807		// TODO(b/): Clean temporary heuristic to avoid unexpected onboarding.
808		defaultUnitTest := !inList("tradefed", j.properties.Libs) && !inList("cts", j.testProperties.Test_suites)
809		j.testProperties.Test_options.Unit_test = proptools.BoolPtr(defaultUnitTest)
810	}
811	j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template,
812		j.testProperties.Test_suites, j.testProperties.Auto_gen_config, j.testProperties.Test_options.Unit_test)
813
814	j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
815
816	j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs)
817
818	ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) {
819		j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
820	})
821
822	ctx.VisitDirectDepsWithTag(jniLibTag, func(dep android.Module) {
823		sharedLibInfo := ctx.OtherModuleProvider(dep, cc.SharedLibraryInfoProvider).(cc.SharedLibraryInfo)
824		if sharedLibInfo.SharedLibrary != nil {
825			// Copy to an intermediate output directory to append "lib[64]" to the path,
826			// so that it's compatible with the default rpath values.
827			var relPath string
828			if sharedLibInfo.Target.Arch.ArchType.Multilib == "lib64" {
829				relPath = filepath.Join("lib64", sharedLibInfo.SharedLibrary.Base())
830			} else {
831				relPath = filepath.Join("lib", sharedLibInfo.SharedLibrary.Base())
832			}
833			relocatedLib := android.PathForModuleOut(ctx, "relocated").Join(ctx, relPath)
834			ctx.Build(pctx, android.BuildParams{
835				Rule:   android.Cp,
836				Input:  sharedLibInfo.SharedLibrary,
837				Output: relocatedLib,
838			})
839			j.data = append(j.data, relocatedLib)
840		} else {
841			ctx.PropertyErrorf("jni_libs", "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep))
842		}
843	})
844
845	j.Library.GenerateAndroidBuildActions(ctx)
846}
847
848func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
849	j.Library.GenerateAndroidBuildActions(ctx)
850}
851
852func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
853	j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.prebuiltTestProperties.Test_config, nil,
854		j.prebuiltTestProperties.Test_suites, nil, nil)
855
856	j.Import.GenerateAndroidBuildActions(ctx)
857}
858
859type testSdkMemberType struct {
860	android.SdkMemberTypeBase
861}
862
863func (mt *testSdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
864	mctx.AddVariationDependencies(nil, dependencyTag, names...)
865}
866
867func (mt *testSdkMemberType) IsInstance(module android.Module) bool {
868	_, ok := module.(*Test)
869	return ok
870}
871
872func (mt *testSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
873	return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_test_import")
874}
875
876func (mt *testSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
877	return &testSdkMemberProperties{}
878}
879
880type testSdkMemberProperties struct {
881	android.SdkMemberPropertiesBase
882
883	JarToExport android.Path
884	TestConfig  android.Path
885}
886
887func (p *testSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
888	test := variant.(*Test)
889
890	implementationJars := test.ImplementationJars()
891	if len(implementationJars) != 1 {
892		panic(fmt.Errorf("there must be only one implementation jar from %q", test.Name()))
893	}
894
895	p.JarToExport = implementationJars[0]
896	p.TestConfig = test.testConfig
897}
898
899func (p *testSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
900	builder := ctx.SnapshotBuilder()
901
902	exportedJar := p.JarToExport
903	if exportedJar != nil {
904		snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(p.OsPrefix(), ctx.Name())
905		builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath)
906
907		propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
908	}
909
910	testConfig := p.TestConfig
911	if testConfig != nil {
912		snapshotRelativeTestConfigPath := sdkSnapshotFilePathForMember(p.OsPrefix(), ctx.Name(), testConfigSuffix)
913		builder.CopyToSnapshot(testConfig, snapshotRelativeTestConfigPath)
914		propertySet.AddProperty("test_config", snapshotRelativeTestConfigPath)
915	}
916}
917
918// java_test builds a and links sources into a `.jar` file for the device, and possibly for the host as well, and
919// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
920//
921// By default, a java_test has a single variant that produces a `.jar` file containing `classes.dex` files that were
922// compiled against the device bootclasspath.
923//
924// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
925// compiled against the host bootclasspath.
926func TestFactory() android.Module {
927	module := &Test{}
928
929	module.addHostAndDeviceProperties()
930	module.AddProperties(&module.testProperties)
931
932	module.Module.properties.Installable = proptools.BoolPtr(true)
933	module.Module.dexpreopter.isTest = true
934	module.Module.linter.test = true
935
936	android.InitSdkAwareModule(module)
937	InitJavaModule(module, android.HostAndDeviceSupported)
938	return module
939}
940
941// java_test_helper_library creates a java library and makes sure that it is added to the appropriate test suite.
942func TestHelperLibraryFactory() android.Module {
943	module := &TestHelperLibrary{}
944
945	module.addHostAndDeviceProperties()
946	module.AddProperties(&module.testHelperLibraryProperties)
947
948	module.Module.properties.Installable = proptools.BoolPtr(true)
949	module.Module.dexpreopter.isTest = true
950	module.Module.linter.test = true
951
952	InitJavaModule(module, android.HostAndDeviceSupported)
953	return module
954}
955
956// java_test_import imports one or more `.jar` files into the build graph as if they were built by a java_test module
957// and makes sure that it is added to the appropriate test suite.
958//
959// By default, a java_test_import has a single variant that expects a `.jar` file containing `.class` files that were
960// compiled against an Android classpath.
961//
962// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
963// for host modules.
964func JavaTestImportFactory() android.Module {
965	module := &JavaTestImport{}
966
967	module.AddProperties(
968		&module.Import.properties,
969		&module.prebuiltTestProperties)
970
971	module.Import.properties.Installable = proptools.BoolPtr(true)
972
973	android.InitPrebuiltModule(module, &module.properties.Jars)
974	android.InitApexModule(module)
975	android.InitSdkAwareModule(module)
976	InitJavaModule(module, android.HostAndDeviceSupported)
977	return module
978}
979
980// java_test_host builds a and links sources into a `.jar` file for the host, and creates an `AndroidTest.xml` file to
981// allow running the test with `atest` or a `TEST_MAPPING` file.
982//
983// A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were
984// compiled against the host bootclasspath.
985func TestHostFactory() android.Module {
986	module := &TestHost{}
987
988	module.addHostProperties()
989	module.AddProperties(&module.testProperties)
990	module.AddProperties(&module.testHostProperties)
991
992	InitTestHost(
993		module,
994		proptools.BoolPtr(true),
995		nil,
996		nil)
997
998	InitJavaModuleMultiTargets(module, android.HostSupported)
999
1000	return module
1001}
1002
1003func InitTestHost(th *TestHost, installable *bool, testSuites []string, autoGenConfig *bool) {
1004	th.properties.Installable = installable
1005	th.testProperties.Auto_gen_config = autoGenConfig
1006	th.testProperties.Test_suites = testSuites
1007}
1008
1009//
1010// Java Binaries (.jar file plus wrapper script)
1011//
1012
1013type binaryProperties struct {
1014	// installable script to execute the resulting jar
1015	Wrapper *string `android:"path"`
1016
1017	// Name of the class containing main to be inserted into the manifest as Main-Class.
1018	Main_class *string
1019
1020	// Names of modules containing JNI libraries that should be installed alongside the host
1021	// variant of the binary.
1022	Jni_libs []string
1023}
1024
1025type Binary struct {
1026	Library
1027
1028	binaryProperties binaryProperties
1029
1030	isWrapperVariant bool
1031
1032	wrapperFile android.Path
1033	binaryFile  android.InstallPath
1034}
1035
1036func (j *Binary) HostToolPath() android.OptionalPath {
1037	return android.OptionalPathForPath(j.binaryFile)
1038}
1039
1040func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1041	if ctx.Arch().ArchType == android.Common {
1042		// Compile the jar
1043		if j.binaryProperties.Main_class != nil {
1044			if j.properties.Manifest != nil {
1045				ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set")
1046			}
1047			manifestFile := android.PathForModuleOut(ctx, "manifest.txt")
1048			GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class))
1049			j.overrideManifest = android.OptionalPathForPath(manifestFile)
1050		}
1051
1052		j.Library.GenerateAndroidBuildActions(ctx)
1053	} else {
1054		// Handle the binary wrapper
1055		j.isWrapperVariant = true
1056
1057		if j.binaryProperties.Wrapper != nil {
1058			j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper)
1059		} else {
1060			j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh")
1061		}
1062
1063		// The host installation rules make the installed wrapper depend on all the dependencies
1064		// of the wrapper variant, which will include the common variant's jar file and any JNI
1065		// libraries.  This is verified by TestBinary.
1066		j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"),
1067			ctx.ModuleName(), j.wrapperFile)
1068	}
1069}
1070
1071func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
1072	if ctx.Arch().ArchType == android.Common || ctx.BazelConversionMode() {
1073		j.deps(ctx)
1074	}
1075	if ctx.Arch().ArchType != android.Common || ctx.BazelConversionMode() {
1076		// These dependencies ensure the host installation rules will install the jar file and
1077		// the jni libraries when the wrapper is installed.
1078		ctx.AddVariationDependencies(nil, jniInstallTag, j.binaryProperties.Jni_libs...)
1079		ctx.AddVariationDependencies(
1080			[]blueprint.Variation{{Mutator: "arch", Variation: android.CommonArch.String()}},
1081			binaryInstallTag, ctx.ModuleName())
1082	}
1083}
1084
1085// java_binary builds a `.jar` file and a shell script that executes it for the device, and possibly for the host
1086// as well.
1087//
1088// By default, a java_binary has a single variant that produces a `.jar` file containing `classes.dex` files that were
1089// compiled against the device bootclasspath.
1090//
1091// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
1092// compiled against the host bootclasspath.
1093func BinaryFactory() android.Module {
1094	module := &Binary{}
1095
1096	module.addHostAndDeviceProperties()
1097	module.AddProperties(&module.binaryProperties)
1098
1099	module.Module.properties.Installable = proptools.BoolPtr(true)
1100
1101	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst)
1102	android.InitDefaultableModule(module)
1103	return module
1104}
1105
1106// java_binary_host builds a `.jar` file and a shell script that executes it for the host.
1107//
1108// A java_binary_host has a single variant that produces a `.jar` file containing `.class` files that were
1109// compiled against the host bootclasspath.
1110func BinaryHostFactory() android.Module {
1111	module := &Binary{}
1112
1113	module.addHostProperties()
1114	module.AddProperties(&module.binaryProperties)
1115
1116	module.Module.properties.Installable = proptools.BoolPtr(true)
1117
1118	android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst)
1119	android.InitDefaultableModule(module)
1120	return module
1121}
1122
1123//
1124// Java prebuilts
1125//
1126
1127type ImportProperties struct {
1128	Jars []string `android:"path,arch_variant"`
1129
1130	// The version of the SDK that the source prebuilt file was built against. Defaults to the
1131	// current version if not specified.
1132	Sdk_version *string
1133
1134	// The minimum version of the SDK that this module supports. Defaults to sdk_version if not
1135	// specified.
1136	Min_sdk_version *string
1137
1138	Installable *bool
1139
1140	// If not empty, classes are restricted to the specified packages and their sub-packages.
1141	// This information is used to generate the updatable-bcp-packages.txt file.
1142	Permitted_packages []string
1143
1144	// List of shared java libs that this module has dependencies to
1145	Libs []string
1146
1147	// List of files to remove from the jar file(s)
1148	Exclude_files []string
1149
1150	// List of directories to remove from the jar file(s)
1151	Exclude_dirs []string
1152
1153	// if set to true, run Jetifier against .jar file. Defaults to false.
1154	Jetifier *bool
1155
1156	// set the name of the output
1157	Stem *string
1158
1159	Aidl struct {
1160		// directories that should be added as include directories for any aidl sources of modules
1161		// that depend on this module, as well as to aidl for this module.
1162		Export_include_dirs []string
1163	}
1164}
1165
1166type Import struct {
1167	android.ModuleBase
1168	android.DefaultableModuleBase
1169	android.ApexModuleBase
1170	prebuilt android.Prebuilt
1171	android.SdkBase
1172
1173	// Functionality common to Module and Import.
1174	embeddableInModuleAndImport
1175
1176	hiddenAPI
1177	dexer
1178	dexpreopter
1179
1180	properties ImportProperties
1181
1182	// output file containing classes.dex and resources
1183	dexJarFile android.Path
1184
1185	combinedClasspathFile android.Path
1186	classLoaderContexts   dexpreopt.ClassLoaderContextMap
1187	exportAidlIncludeDirs android.Paths
1188
1189	hideApexVariantFromMake bool
1190
1191	sdkVersion    android.SdkSpec
1192	minSdkVersion android.SdkSpec
1193}
1194
1195var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil)
1196
1197func (j *Import) PermittedPackagesForUpdatableBootJars() []string {
1198	return j.properties.Permitted_packages
1199}
1200
1201func (j *Import) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
1202	return android.SdkSpecFrom(ctx, String(j.properties.Sdk_version))
1203}
1204
1205func (j *Import) SystemModules() string {
1206	return "none"
1207}
1208
1209func (j *Import) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
1210	if j.properties.Min_sdk_version != nil {
1211		return android.SdkSpecFrom(ctx, *j.properties.Min_sdk_version)
1212	}
1213	return j.SdkVersion(ctx)
1214}
1215
1216func (j *Import) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
1217	return j.SdkVersion(ctx)
1218}
1219
1220func (j *Import) Prebuilt() *android.Prebuilt {
1221	return &j.prebuilt
1222}
1223
1224func (j *Import) PrebuiltSrcs() []string {
1225	return j.properties.Jars
1226}
1227
1228func (j *Import) Name() string {
1229	return j.prebuilt.Name(j.ModuleBase.Name())
1230}
1231
1232func (j *Import) Stem() string {
1233	return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
1234}
1235
1236func (a *Import) JacocoReportClassesFile() android.Path {
1237	return nil
1238}
1239
1240func (j *Import) LintDepSets() LintDepSets {
1241	return LintDepSets{}
1242}
1243
1244func (j *Import) getStrictUpdatabilityLinting() bool {
1245	return false
1246}
1247
1248func (j *Import) setStrictUpdatabilityLinting(bool) {
1249}
1250
1251func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
1252	ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
1253
1254	if ctx.Device() && Bool(j.dexProperties.Compile_dex) {
1255		sdkDeps(ctx, android.SdkContext(j), j.dexer)
1256	}
1257}
1258
1259func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1260	j.sdkVersion = j.SdkVersion(ctx)
1261	j.minSdkVersion = j.MinSdkVersion(ctx)
1262
1263	if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() {
1264		j.hideApexVariantFromMake = true
1265	}
1266
1267	jars := android.PathsForModuleSrc(ctx, j.properties.Jars)
1268
1269	jarName := j.Stem() + ".jar"
1270	outputFile := android.PathForModuleOut(ctx, "combined", jarName)
1271	TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{},
1272		false, j.properties.Exclude_files, j.properties.Exclude_dirs)
1273	if Bool(j.properties.Jetifier) {
1274		inputFile := outputFile
1275		outputFile = android.PathForModuleOut(ctx, "jetifier", jarName)
1276		TransformJetifier(ctx, outputFile, inputFile)
1277	}
1278	j.combinedClasspathFile = outputFile
1279	j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
1280
1281	var flags javaBuilderFlags
1282	var deapexerModule android.Module
1283
1284	ctx.VisitDirectDeps(func(module android.Module) {
1285		tag := ctx.OtherModuleDependencyTag(module)
1286
1287		if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
1288			dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
1289			switch tag {
1290			case libTag, staticLibTag:
1291				flags.classpath = append(flags.classpath, dep.HeaderJars...)
1292			case bootClasspathTag:
1293				flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...)
1294			}
1295		} else if dep, ok := module.(SdkLibraryDependency); ok {
1296			switch tag {
1297			case libTag:
1298				flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...)
1299			}
1300		}
1301
1302		addCLCFromDep(ctx, module, j.classLoaderContexts)
1303
1304		// Save away the `deapexer` module on which this depends, if any.
1305		if tag == android.DeapexerTag {
1306			if deapexerModule != nil {
1307				ctx.ModuleErrorf("Ambiguous duplicate deapexer module dependencies %q and %q",
1308					deapexerModule.Name(), module.Name())
1309			}
1310			deapexerModule = module
1311		}
1312	})
1313
1314	if Bool(j.properties.Installable) {
1315		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
1316			jarName, outputFile)
1317	}
1318
1319	j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs)
1320
1321	if ctx.Device() {
1322		// If this is a variant created for a prebuilt_apex then use the dex implementation jar
1323		// obtained from the associated deapexer module.
1324		ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
1325		if ai.ForPrebuiltApex {
1326			if deapexerModule == nil {
1327				// This should never happen as a variant for a prebuilt_apex is only created if the
1328				// deapexer module has been configured to export the dex implementation jar for this module.
1329				ctx.ModuleErrorf("internal error: module %q does not depend on a `deapexer` module for prebuilt_apex %q",
1330					j.Name(), ai.ApexVariationName)
1331				return
1332			}
1333
1334			// Get the path of the dex implementation jar from the `deapexer` module.
1335			di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo)
1336			if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil {
1337				j.dexJarFile = dexOutputPath
1338
1339				// Initialize the hiddenapi structure.
1340				j.initHiddenAPI(ctx, dexOutputPath, outputFile, nil)
1341			} else {
1342				// This should never happen as a variant for a prebuilt_apex is only created if the
1343				// prebuilt_apex has been configured to export the java library dex file.
1344				ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt_apex %q", deapexerModule.Name())
1345			}
1346		} else if Bool(j.dexProperties.Compile_dex) {
1347			sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
1348			if sdkDep.invalidVersion {
1349				ctx.AddMissingDependencies(sdkDep.bootclasspath)
1350				ctx.AddMissingDependencies(sdkDep.java9Classpath)
1351			} else if sdkDep.useFiles {
1352				// sdkDep.jar is actually equivalent to turbine header.jar.
1353				flags.classpath = append(flags.classpath, sdkDep.jars...)
1354			}
1355
1356			// Dex compilation
1357
1358			j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", jarName)
1359			if j.dexProperties.Uncompress_dex == nil {
1360				// If the value was not force-set by the user, use reasonable default based on the module.
1361				j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
1362			}
1363			j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
1364
1365			var dexOutputFile android.OutputPath
1366			dexOutputFile = j.dexer.compileDex(ctx, flags, j.MinSdkVersion(ctx), outputFile, jarName)
1367			if ctx.Failed() {
1368				return
1369			}
1370
1371			// Initialize the hiddenapi structure.
1372			j.initHiddenAPI(ctx, dexOutputFile, outputFile, j.dexProperties.Uncompress_dex)
1373
1374			// Encode hidden API flags in dex file.
1375			dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)
1376
1377			j.dexJarFile = dexOutputFile
1378		}
1379	}
1380
1381	ctx.SetProvider(JavaInfoProvider, JavaInfo{
1382		HeaderJars:                     android.PathsIfNonNil(j.combinedClasspathFile),
1383		ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile),
1384		ImplementationJars:             android.PathsIfNonNil(j.combinedClasspathFile),
1385		AidlIncludeDirs:                j.exportAidlIncludeDirs,
1386	})
1387}
1388
1389func (j *Import) OutputFiles(tag string) (android.Paths, error) {
1390	switch tag {
1391	case "", ".jar":
1392		return android.Paths{j.combinedClasspathFile}, nil
1393	default:
1394		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1395	}
1396}
1397
1398var _ android.OutputFileProducer = (*Import)(nil)
1399
1400func (j *Import) HeaderJars() android.Paths {
1401	if j.combinedClasspathFile == nil {
1402		return nil
1403	}
1404	return android.Paths{j.combinedClasspathFile}
1405}
1406
1407func (j *Import) ImplementationAndResourcesJars() android.Paths {
1408	if j.combinedClasspathFile == nil {
1409		return nil
1410	}
1411	return android.Paths{j.combinedClasspathFile}
1412}
1413
1414func (j *Import) DexJarBuildPath() android.Path {
1415	return j.dexJarFile
1416}
1417
1418func (j *Import) DexJarInstallPath() android.Path {
1419	return nil
1420}
1421
1422func (j *Import) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
1423	return j.classLoaderContexts
1424}
1425
1426var _ android.ApexModule = (*Import)(nil)
1427
1428// Implements android.ApexModule
1429func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1430	return j.depIsInSameApex(ctx, dep)
1431}
1432
1433// Implements android.ApexModule
1434func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
1435	sdkVersion android.ApiLevel) error {
1436	sdkSpec := j.MinSdkVersion(ctx)
1437	if !sdkSpec.Specified() {
1438		return fmt.Errorf("min_sdk_version is not specified")
1439	}
1440	if sdkSpec.Kind == android.SdkCore {
1441		return nil
1442	}
1443	ver, err := sdkSpec.EffectiveVersion(ctx)
1444	if err != nil {
1445		return err
1446	}
1447	if ver.GreaterThan(sdkVersion) {
1448		return fmt.Errorf("newer SDK(%v)", ver)
1449	}
1450	return nil
1451}
1452
1453// requiredFilesFromPrebuiltApexForImport returns information about the files that a java_import or
1454// java_sdk_library_import with the specified base module name requires to be exported from a
1455// prebuilt_apex/apex_set.
1456func requiredFilesFromPrebuiltApexForImport(name string) []string {
1457	// Add the dex implementation jar to the set of exported files.
1458	return []string{
1459		apexRootRelativePathToJavaLib(name),
1460	}
1461}
1462
1463// apexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for
1464// the java library with the specified name.
1465func apexRootRelativePathToJavaLib(name string) string {
1466	return filepath.Join("javalib", name+".jar")
1467}
1468
1469var _ android.RequiredFilesFromPrebuiltApex = (*Import)(nil)
1470
1471func (j *Import) RequiredFilesFromPrebuiltApex(_ android.BaseModuleContext) []string {
1472	name := j.BaseModuleName()
1473	return requiredFilesFromPrebuiltApexForImport(name)
1474}
1475
1476// Add compile time check for interface implementation
1477var _ android.IDEInfo = (*Import)(nil)
1478var _ android.IDECustomizedModuleName = (*Import)(nil)
1479
1480// Collect information for opening IDE project files in java/jdeps.go.
1481const (
1482	removedPrefix = "prebuilt_"
1483)
1484
1485func (j *Import) IDEInfo(dpInfo *android.IdeInfo) {
1486	dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...)
1487}
1488
1489func (j *Import) IDECustomizedModuleName() string {
1490	// TODO(b/113562217): Extract the base module name from the Import name, often the Import name
1491	// has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better
1492	// solution to get the Import name.
1493	name := j.Name()
1494	if strings.HasPrefix(name, removedPrefix) {
1495		name = strings.TrimPrefix(name, removedPrefix)
1496	}
1497	return name
1498}
1499
1500var _ android.PrebuiltInterface = (*Import)(nil)
1501
1502func (j *Import) IsInstallable() bool {
1503	return Bool(j.properties.Installable)
1504}
1505
1506var _ dexpreopterInterface = (*Import)(nil)
1507
1508// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module.
1509//
1510// By default, a java_import has a single variant that expects a `.jar` file containing `.class` files that were
1511// compiled against an Android classpath.
1512//
1513// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
1514// for host modules.
1515func ImportFactory() android.Module {
1516	module := &Import{}
1517
1518	module.AddProperties(
1519		&module.properties,
1520		&module.dexer.dexProperties,
1521	)
1522
1523	module.initModuleAndImport(module)
1524
1525	module.dexProperties.Optimize.EnabledByDefault = false
1526
1527	android.InitPrebuiltModule(module, &module.properties.Jars)
1528	android.InitApexModule(module)
1529	android.InitSdkAwareModule(module)
1530	InitJavaModule(module, android.HostAndDeviceSupported)
1531	return module
1532}
1533
1534// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library_host
1535// module.
1536//
1537// A java_import_host has a single variant that expects a `.jar` file containing `.class` files that were
1538// compiled against a host bootclasspath.
1539func ImportFactoryHost() android.Module {
1540	module := &Import{}
1541
1542	module.AddProperties(&module.properties)
1543
1544	android.InitPrebuiltModule(module, &module.properties.Jars)
1545	android.InitApexModule(module)
1546	InitJavaModule(module, android.HostSupported)
1547	return module
1548}
1549
1550// dex_import module
1551
1552type DexImportProperties struct {
1553	Jars []string `android:"path"`
1554
1555	// set the name of the output
1556	Stem *string
1557}
1558
1559type DexImport struct {
1560	android.ModuleBase
1561	android.DefaultableModuleBase
1562	android.ApexModuleBase
1563	prebuilt android.Prebuilt
1564
1565	properties DexImportProperties
1566
1567	dexJarFile android.Path
1568
1569	dexpreopter
1570
1571	hideApexVariantFromMake bool
1572}
1573
1574func (j *DexImport) Prebuilt() *android.Prebuilt {
1575	return &j.prebuilt
1576}
1577
1578func (j *DexImport) PrebuiltSrcs() []string {
1579	return j.properties.Jars
1580}
1581
1582func (j *DexImport) Name() string {
1583	return j.prebuilt.Name(j.ModuleBase.Name())
1584}
1585
1586func (j *DexImport) Stem() string {
1587	return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
1588}
1589
1590func (a *DexImport) JacocoReportClassesFile() android.Path {
1591	return nil
1592}
1593
1594func (a *DexImport) LintDepSets() LintDepSets {
1595	return LintDepSets{}
1596}
1597
1598func (j *DexImport) IsInstallable() bool {
1599	return true
1600}
1601
1602func (j *DexImport) getStrictUpdatabilityLinting() bool {
1603	return false
1604}
1605
1606func (j *DexImport) setStrictUpdatabilityLinting(bool) {
1607}
1608
1609func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1610	if len(j.properties.Jars) != 1 {
1611		ctx.PropertyErrorf("jars", "exactly one jar must be provided")
1612	}
1613
1614	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
1615	if !apexInfo.IsForPlatform() {
1616		j.hideApexVariantFromMake = true
1617	}
1618
1619	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
1620	j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
1621
1622	inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars")
1623	dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar")
1624
1625	if j.dexpreopter.uncompressedDex {
1626		rule := android.NewRuleBuilder(pctx, ctx)
1627
1628		temporary := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar.unaligned")
1629		rule.Temporary(temporary)
1630
1631		// use zip2zip to uncompress classes*.dex files
1632		rule.Command().
1633			BuiltTool("zip2zip").
1634			FlagWithInput("-i ", inputJar).
1635			FlagWithOutput("-o ", temporary).
1636			FlagWithArg("-0 ", "'classes*.dex'")
1637
1638		// use zipalign to align uncompressed classes*.dex files
1639		rule.Command().
1640			BuiltTool("zipalign").
1641			Flag("-f").
1642			Text("4").
1643			Input(temporary).
1644			Output(dexOutputFile)
1645
1646		rule.DeleteTemporaryFiles()
1647
1648		rule.Build("uncompress_dex", "uncompress dex")
1649	} else {
1650		ctx.Build(pctx, android.BuildParams{
1651			Rule:   android.Cp,
1652			Input:  inputJar,
1653			Output: dexOutputFile,
1654		})
1655	}
1656
1657	j.dexJarFile = dexOutputFile
1658
1659	j.dexpreopt(ctx, dexOutputFile)
1660
1661	if apexInfo.IsForPlatform() {
1662		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
1663			j.Stem()+".jar", dexOutputFile)
1664	}
1665}
1666
1667func (j *DexImport) DexJarBuildPath() android.Path {
1668	return j.dexJarFile
1669}
1670
1671var _ android.ApexModule = (*DexImport)(nil)
1672
1673// Implements android.ApexModule
1674func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
1675	sdkVersion android.ApiLevel) error {
1676	// we don't check prebuilt modules for sdk_version
1677	return nil
1678}
1679
1680// dex_import imports a `.jar` file containing classes.dex files.
1681//
1682// A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed
1683// to the device.
1684func DexImportFactory() android.Module {
1685	module := &DexImport{}
1686
1687	module.AddProperties(&module.properties)
1688
1689	android.InitPrebuiltModule(module, &module.properties.Jars)
1690	android.InitApexModule(module)
1691	InitJavaModule(module, android.DeviceSupported)
1692	return module
1693}
1694
1695//
1696// Defaults
1697//
1698type Defaults struct {
1699	android.ModuleBase
1700	android.DefaultsModuleBase
1701	android.ApexModuleBase
1702}
1703
1704// java_defaults provides a set of properties that can be inherited by other java or android modules.
1705//
1706// A module can use the properties from a java_defaults module using `defaults: ["defaults_module_name"]`.  Each
1707// property in the defaults module that exists in the depending module will be prepended to the depending module's
1708// value for that property.
1709//
1710// Example:
1711//
1712//     java_defaults {
1713//         name: "example_defaults",
1714//         srcs: ["common/**/*.java"],
1715//         javacflags: ["-Xlint:all"],
1716//         aaptflags: ["--auto-add-overlay"],
1717//     }
1718//
1719//     java_library {
1720//         name: "example",
1721//         defaults: ["example_defaults"],
1722//         srcs: ["example/**/*.java"],
1723//     }
1724//
1725// is functionally identical to:
1726//
1727//     java_library {
1728//         name: "example",
1729//         srcs: [
1730//             "common/**/*.java",
1731//             "example/**/*.java",
1732//         ],
1733//         javacflags: ["-Xlint:all"],
1734//     }
1735func DefaultsFactory() android.Module {
1736	module := &Defaults{}
1737
1738	module.AddProperties(
1739		&CommonProperties{},
1740		&DeviceProperties{},
1741		&DexProperties{},
1742		&DexpreoptProperties{},
1743		&android.ProtoProperties{},
1744		&aaptProperties{},
1745		&androidLibraryProperties{},
1746		&appProperties{},
1747		&appTestProperties{},
1748		&overridableAppProperties{},
1749		&testProperties{},
1750		&ImportProperties{},
1751		&AARImportProperties{},
1752		&sdkLibraryProperties{},
1753		&commonToSdkLibraryAndImportProperties{},
1754		&DexImportProperties{},
1755		&android.ApexProperties{},
1756		&RuntimeResourceOverlayProperties{},
1757		&LintProperties{},
1758		&appTestHelperAppProperties{},
1759	)
1760
1761	android.InitDefaultsModule(module)
1762	return module
1763}
1764
1765func kytheExtractJavaFactory() android.Singleton {
1766	return &kytheExtractJavaSingleton{}
1767}
1768
1769type kytheExtractJavaSingleton struct {
1770}
1771
1772func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) {
1773	var xrefTargets android.Paths
1774	ctx.VisitAllModules(func(module android.Module) {
1775		if javaModule, ok := module.(xref); ok {
1776			xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...)
1777		}
1778	})
1779	// TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets
1780	if len(xrefTargets) > 0 {
1781		ctx.Phony("xref_java", xrefTargets...)
1782	}
1783}
1784
1785var Bool = proptools.Bool
1786var BoolDefault = proptools.BoolDefault
1787var String = proptools.String
1788var inList = android.InList
1789
1790// Add class loader context (CLC) of a given dependency to the current CLC.
1791func addCLCFromDep(ctx android.ModuleContext, depModule android.Module,
1792	clcMap dexpreopt.ClassLoaderContextMap) {
1793
1794	dep, ok := depModule.(UsesLibraryDependency)
1795	if !ok {
1796		return
1797	}
1798
1799	// Find out if the dependency is either an SDK library or an ordinary library that is disguised
1800	// as an SDK library by the means of `provides_uses_lib` property. If yes, the library is itself
1801	// a <uses-library> and should be added as a node in the CLC tree, and its CLC should be added
1802	// as subtree of that node. Otherwise the library is not a <uses_library> and should not be
1803	// added to CLC, but the transitive <uses-library> dependencies from its CLC should be added to
1804	// the current CLC.
1805	var implicitSdkLib *string
1806	comp, isComp := depModule.(SdkLibraryComponentDependency)
1807	if isComp {
1808		implicitSdkLib = comp.OptionalImplicitSdkLibrary()
1809		// OptionalImplicitSdkLibrary() may be nil so need to fall through to ProvidesUsesLib().
1810	}
1811	if implicitSdkLib == nil {
1812		if ulib, ok := depModule.(ProvidesUsesLib); ok {
1813			implicitSdkLib = ulib.ProvidesUsesLib()
1814		}
1815	}
1816
1817	depTag := ctx.OtherModuleDependencyTag(depModule)
1818	if depTag == libTag || depTag == usesLibTag {
1819		// Ok, propagate <uses-library> through non-static library dependencies.
1820	} else if depTag == staticLibTag {
1821		// Propagate <uses-library> through static library dependencies, unless it is a component
1822		// library (such as stubs). Component libraries have a dependency on their SDK library,
1823		// which should not be pulled just because of a static component library.
1824		if implicitSdkLib != nil {
1825			return
1826		}
1827	} else {
1828		// Don't propagate <uses-library> for other dependency tags.
1829		return
1830	}
1831
1832	if implicitSdkLib != nil {
1833		clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *implicitSdkLib,
1834			dep.DexJarBuildPath(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
1835	} else {
1836		depName := ctx.OtherModuleName(depModule)
1837		clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
1838	}
1839}
1840