// Copyright 2015 Google Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package java // This file contains the module types for compiling Java for Android, and converts the properties // into the flags and filenames necessary to pass to the Module. The final creation of the rules // is handled in builder.go import ( "fmt" "path/filepath" "slices" "sort" "strings" "android/soong/remoteexec" "android/soong/testing" "github.com/google/blueprint" "github.com/google/blueprint/proptools" "android/soong/android" "android/soong/cc" "android/soong/dexpreopt" "android/soong/java/config" "android/soong/tradefed" ) func init() { registerJavaBuildComponents(android.InitRegistrationContext) RegisterJavaSdkMemberTypes() } func registerJavaBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("java_defaults", DefaultsFactory) ctx.RegisterModuleType("java_library", LibraryFactory) ctx.RegisterModuleType("java_library_static", LibraryStaticFactory) ctx.RegisterModuleType("java_library_host", LibraryHostFactory) ctx.RegisterModuleType("java_binary", BinaryFactory) ctx.RegisterModuleType("java_binary_host", BinaryHostFactory) ctx.RegisterModuleType("java_test", TestFactory) ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory) ctx.RegisterModuleType("java_test_host", TestHostFactory) ctx.RegisterModuleType("java_test_import", JavaTestImportFactory) ctx.RegisterModuleType("java_import", ImportFactory) ctx.RegisterModuleType("java_import_host", ImportFactoryHost) ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory) ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory) ctx.RegisterModuleType("dex_import", DexImportFactory) ctx.RegisterModuleType("java_api_library", ApiLibraryFactory) ctx.RegisterModuleType("java_api_contribution", ApiContributionFactory) ctx.RegisterModuleType("java_api_contribution_import", ApiContributionImportFactory) // This mutator registers dependencies on dex2oat for modules that should be // dexpreopted. This is done late when the final variants have been // established, to not get the dependencies split into the wrong variants and // to support the checks in dexpreoptDisabled(). ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel() // needs access to ApexInfoProvider which is available after variant creation ctx.BottomUp("jacoco_deps", jacocoDepsMutator).Parallel() }) ctx.RegisterParallelSingletonType("logtags", LogtagsSingleton) ctx.RegisterParallelSingletonType("kythe_java_extract", kytheExtractJavaFactory) } func RegisterJavaSdkMemberTypes() { // Register sdk member types. android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType) android.RegisterSdkMemberType(javaLibsSdkMemberType) android.RegisterSdkMemberType(JavaBootLibsSdkMemberType) android.RegisterSdkMemberType(JavaSystemserverLibsSdkMemberType) android.RegisterSdkMemberType(javaTestSdkMemberType) } type StubsLinkType int const ( Unknown StubsLinkType = iota Stubs Implementation ) var ( // Supports adding java header libraries to module_exports and sdk. javaHeaderLibsSdkMemberType = &librarySdkMemberType{ android.SdkMemberTypeBase{ PropertyName: "java_header_libs", SupportsSdk: true, }, func(_ android.SdkMemberContext, j *Library) android.Path { headerJars := j.HeaderJars() if len(headerJars) != 1 { panic(fmt.Errorf("there must be only one header jar from %q", j.Name())) } return headerJars[0] }, sdkSnapshotFilePathForJar, copyEverythingToSnapshot, } // Export implementation classes jar as part of the sdk. exportImplementationClassesJar = func(_ android.SdkMemberContext, j *Library) android.Path { implementationJars := j.ImplementationAndResourcesJars() if len(implementationJars) != 1 { panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name())) } return implementationJars[0] } // Supports adding java implementation libraries to module_exports but not sdk. javaLibsSdkMemberType = &librarySdkMemberType{ android.SdkMemberTypeBase{ PropertyName: "java_libs", }, exportImplementationClassesJar, sdkSnapshotFilePathForJar, copyEverythingToSnapshot, } snapshotRequiresImplementationJar = func(ctx android.SdkMemberContext) bool { // In the S build the build will break if updatable-media does not provide a full implementation // jar. That issue was fixed in Tiramisu by b/229932396. if ctx.IsTargetBuildBeforeTiramisu() && ctx.Name() == "updatable-media" { return true } return false } // Supports adding java boot libraries to module_exports and sdk. // // The build has some implicit dependencies (via the boot jars configuration) on a number of // modules, e.g. core-oj, apache-xml, that are part of the java boot class path and which are // provided by mainline modules (e.g. art, conscrypt, runtime-i18n) but which are not otherwise // used outside those mainline modules. // // As they are not needed outside the mainline modules adding them to the sdk/module-exports as // either java_libs, or java_header_libs would end up exporting more information than was strictly // necessary. The java_boot_libs property to allow those modules to be exported as part of the // sdk/module_exports without exposing any unnecessary information. JavaBootLibsSdkMemberType = &librarySdkMemberType{ android.SdkMemberTypeBase{ PropertyName: "java_boot_libs", SupportsSdk: true, }, func(ctx android.SdkMemberContext, j *Library) android.Path { if snapshotRequiresImplementationJar(ctx) { return exportImplementationClassesJar(ctx, j) } // Java boot libs are only provided in the SDK to provide access to their dex implementation // jar for use by dexpreopting and boot jars package check. They do not need to provide an // actual implementation jar but the java_import will need a file that exists so just copy an // empty file. Any attempt to use that file as a jar will cause a build error. return ctx.SnapshotBuilder().EmptyFile() }, func(ctx android.SdkMemberContext, osPrefix, name string) string { if snapshotRequiresImplementationJar(ctx) { return sdkSnapshotFilePathForJar(ctx, osPrefix, name) } // Create a special name for the implementation jar to try and provide some useful information // to a developer that attempts to compile against this. // TODO(b/175714559): Provide a proper error message in Soong not ninja. return filepath.Join(osPrefix, "java_boot_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) }, onlyCopyJarToSnapshot, } // Supports adding java systemserver libraries to module_exports and sdk. // // The build has some implicit dependencies (via the systemserver jars configuration) on a number // of modules that are part of the java systemserver classpath and which are provided by mainline // modules but which are not otherwise used outside those mainline modules. // // As they are not needed outside the mainline modules adding them to the sdk/module-exports as // either java_libs, or java_header_libs would end up exporting more information than was strictly // necessary. The java_systemserver_libs property to allow those modules to be exported as part of // the sdk/module_exports without exposing any unnecessary information. JavaSystemserverLibsSdkMemberType = &librarySdkMemberType{ android.SdkMemberTypeBase{ PropertyName: "java_systemserver_libs", SupportsSdk: true, // This was only added in Tiramisu. SupportedBuildReleaseSpecification: "Tiramisu+", }, func(ctx android.SdkMemberContext, j *Library) android.Path { // Java systemserver libs are only provided in the SDK to provide access to their dex // implementation jar for use by dexpreopting. They do not need to provide an actual // implementation jar but the java_import will need a file that exists so just copy an empty // file. Any attempt to use that file as a jar will cause a build error. return ctx.SnapshotBuilder().EmptyFile() }, func(_ android.SdkMemberContext, osPrefix, name string) string { // Create a special name for the implementation jar to try and provide some useful information // to a developer that attempts to compile against this. // TODO(b/175714559): Provide a proper error message in Soong not ninja. return filepath.Join(osPrefix, "java_systemserver_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) }, onlyCopyJarToSnapshot, } // Supports adding java test libraries to module_exports but not sdk. javaTestSdkMemberType = &testSdkMemberType{ SdkMemberTypeBase: android.SdkMemberTypeBase{ PropertyName: "java_tests", }, } // Rule for generating device binary default wrapper deviceBinaryWrapper = pctx.StaticRule("deviceBinaryWrapper", blueprint.RuleParams{ Command: `echo -e '#!/system/bin/sh\n` + `export CLASSPATH=/system/framework/$jar_name\n` + `exec app_process /$partition/bin $main_class "$$@"'> ${out}`, Description: "Generating device binary wrapper ${jar_name}", }, "jar_name", "partition", "main_class") ) type ProguardSpecInfo struct { // If true, proguard flags files will be exported to reverse dependencies across libs edges // If false, proguard flags files will only be exported to reverse dependencies across // static_libs edges. Export_proguard_flags_files bool // TransitiveDepsProguardSpecFiles is a depset of paths to proguard flags files that are exported from // all transitive deps. This list includes all proguard flags files from transitive static dependencies, // and all proguard flags files from transitive libs dependencies which set `export_proguard_spec: true`. ProguardFlagsFiles *android.DepSet[android.Path] // implementation detail to store transitive proguard flags files from exporting shared deps UnconditionallyExportedProguardFlags *android.DepSet[android.Path] } var ProguardSpecInfoProvider = blueprint.NewProvider[ProguardSpecInfo]() // JavaInfo contains information about a java module for use by modules that depend on it. type JavaInfo struct { // HeaderJars is a list of jars that can be passed as the javac classpath in order to link // against this module. If empty, ImplementationJars should be used instead. HeaderJars android.Paths RepackagedHeaderJars android.Paths // set of header jars for all transitive libs deps TransitiveLibsHeaderJars *android.DepSet[android.Path] // set of header jars for all transitive static libs deps TransitiveStaticLibsHeaderJars *android.DepSet[android.Path] // ImplementationAndResourceJars is a list of jars that contain the implementations of classes // in the module as well as any resources included in the module. ImplementationAndResourcesJars android.Paths // ImplementationJars is a list of jars that contain the implementations of classes in the //module. ImplementationJars android.Paths // ResourceJars is a list of jars that contain the resources included in the module. ResourceJars android.Paths // AidlIncludeDirs is a list of directories that should be passed to the aidl tool when // depending on this module. AidlIncludeDirs android.Paths // SrcJarArgs is a list of arguments to pass to soong_zip to package the sources of this // module. SrcJarArgs []string // SrcJarDeps is a list of paths to depend on when packaging the sources of this module. SrcJarDeps android.Paths // The source files of this module and all its transitive static dependencies. TransitiveSrcFiles *android.DepSet[android.Path] // ExportedPlugins is a list of paths that should be used as annotation processors for any // module that depends on this module. ExportedPlugins android.Paths // ExportedPluginClasses is a list of classes that should be run as annotation processors for // any module that depends on this module. ExportedPluginClasses []string // ExportedPluginDisableTurbine is true if this module's annotation processors generate APIs, // requiring disbling turbine for any modules that depend on it. ExportedPluginDisableTurbine bool // JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be // instrumented by jacoco. JacocoReportClassesFile android.Path // StubsLinkType provides information about whether the provided jars are stub jars or // implementation jars. If the provider is set by java_sdk_library, the link type is "unknown" // and selection between the stub jar vs implementation jar is deferred to SdkLibrary.sdkJars(...) StubsLinkType StubsLinkType // AconfigIntermediateCacheOutputPaths is a path to the cache files collected from the // java_aconfig_library modules that are statically linked to this module. AconfigIntermediateCacheOutputPaths android.Paths } var JavaInfoProvider = blueprint.NewProvider[JavaInfo]() // SyspropPublicStubInfo contains info about the sysprop public stub library that corresponds to // the sysprop implementation library. type SyspropPublicStubInfo struct { // JavaInfo is the JavaInfoProvider of the sysprop public stub library that corresponds to // the sysprop implementation library. JavaInfo JavaInfo } var SyspropPublicStubInfoProvider = blueprint.NewProvider[SyspropPublicStubInfo]() // Methods that need to be implemented for a module that is added to apex java_libs property. type ApexDependency interface { HeaderJars() android.Paths ImplementationAndResourcesJars() android.Paths } // Provides build path and install path to DEX jars. type UsesLibraryDependency interface { DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath DexJarInstallPath() android.Path ClassLoaderContexts() dexpreopt.ClassLoaderContextMap } // TODO(jungjw): Move this to kythe.go once it's created. type xref interface { XrefJavaFiles() android.Paths } func (j *Module) XrefJavaFiles() android.Paths { return j.kytheFiles } func (d dependencyTag) PropagateAconfigValidation() bool { return d.static } var _ android.PropagateAconfigValidationDependencyTag = dependencyTag{} type dependencyTag struct { blueprint.BaseDependencyTag name string // True if the dependency is relinked at runtime. runtimeLinked bool // True if the dependency is a toolchain, for example an annotation processor. toolchain bool static bool } // installDependencyTag is a dependency tag that is annotated to cause the installed files of the // dependency to be installed when the parent module is installed. type installDependencyTag struct { blueprint.BaseDependencyTag android.InstallAlwaysNeededDependencyTag name string } func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation { if d.runtimeLinked { return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency} } else if d.toolchain { return []android.LicenseAnnotation{android.LicenseAnnotationToolchain} } return nil } var _ android.LicenseAnnotationsDependencyTag = dependencyTag{} type usesLibraryDependencyTag struct { dependencyTag sdkVersion int // SDK version in which the library appared as a standalone library. optional bool // If the dependency is optional or required. } func makeUsesLibraryDependencyTag(sdkVersion int, optional bool) usesLibraryDependencyTag { return usesLibraryDependencyTag{ dependencyTag: dependencyTag{ name: fmt.Sprintf("uses-library-%d", sdkVersion), runtimeLinked: true, }, sdkVersion: sdkVersion, optional: optional, } } func IsJniDepTag(depTag blueprint.DependencyTag) bool { return depTag == jniLibTag } var ( dataNativeBinsTag = dependencyTag{name: "dataNativeBins"} dataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"} staticLibTag = dependencyTag{name: "staticlib", static: true} libTag = dependencyTag{name: "javalib", runtimeLinked: true} sdkLibTag = dependencyTag{name: "sdklib", runtimeLinked: true} java9LibTag = dependencyTag{name: "java9lib", runtimeLinked: true} pluginTag = dependencyTag{name: "plugin", toolchain: true} errorpronePluginTag = dependencyTag{name: "errorprone-plugin", toolchain: true} exportedPluginTag = dependencyTag{name: "exported-plugin", toolchain: true} bootClasspathTag = dependencyTag{name: "bootclasspath", runtimeLinked: true} systemModulesTag = dependencyTag{name: "system modules", runtimeLinked: true} frameworkResTag = dependencyTag{name: "framework-res"} kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib", runtimeLinked: true} kotlinAnnotationsTag = dependencyTag{name: "kotlin-annotations", runtimeLinked: true} kotlinPluginTag = dependencyTag{name: "kotlin-plugin", toolchain: true} proguardRaiseTag = dependencyTag{name: "proguard-raise"} certificateTag = dependencyTag{name: "certificate"} instrumentationForTag = dependencyTag{name: "instrumentation_for"} extraLintCheckTag = dependencyTag{name: "extra-lint-check", toolchain: true} jniLibTag = dependencyTag{name: "jnilib", runtimeLinked: true} r8LibraryJarTag = dependencyTag{name: "r8-libraryjar", runtimeLinked: true} syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"} javaApiContributionTag = dependencyTag{name: "java-api-contribution"} depApiSrcsTag = dependencyTag{name: "dep-api-srcs"} aconfigDeclarationTag = dependencyTag{name: "aconfig-declaration"} jniInstallTag = installDependencyTag{name: "jni install"} binaryInstallTag = installDependencyTag{name: "binary install"} usesLibReqTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false) usesLibOptTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true) usesLibCompat28OptTag = makeUsesLibraryDependencyTag(28, true) usesLibCompat29ReqTag = makeUsesLibraryDependencyTag(29, false) usesLibCompat30OptTag = makeUsesLibraryDependencyTag(30, true) ) func IsLibDepTag(depTag blueprint.DependencyTag) bool { return depTag == libTag || depTag == sdkLibTag } func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool { return depTag == staticLibTag } type sdkDep struct { useModule, useFiles, invalidVersion bool // The modules that will be added to the bootclasspath when targeting 1.8 or lower bootclasspath []string // The default system modules to use. Will be an empty string if no system // modules are to be used. systemModules string // The modules that will be added to the classpath regardless of the Java language level targeted classpath []string // The modules that will be added ot the classpath when targeting 1.9 or higher // (normally these will be on the bootclasspath when targeting 1.8 or lower) java9Classpath []string frameworkResModule string jars android.Paths aidl android.OptionalPath noStandardLibs, noFrameworksLibs bool } func (s sdkDep) hasStandardLibs() bool { return !s.noStandardLibs } func (s sdkDep) hasFrameworkLibs() bool { return !s.noStandardLibs && !s.noFrameworksLibs } type jniLib struct { name string path android.Path target android.Target coverageFile android.OptionalPath unstrippedFile android.Path partition string } func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) { sdkDep := decodeSdkDep(ctx, sdkContext) if sdkDep.useModule { ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...) ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...) ctx.AddVariationDependencies(nil, sdkLibTag, sdkDep.classpath...) if d.effectiveOptimizeEnabled() && sdkDep.hasStandardLibs() { ctx.AddVariationDependencies(nil, proguardRaiseTag, config.LegacyCorePlatformBootclasspathLibraries..., ) } if d.effectiveOptimizeEnabled() && sdkDep.hasFrameworkLibs() { ctx.AddVariationDependencies(nil, proguardRaiseTag, config.FrameworkLibraries...) } } if sdkDep.systemModules != "" { ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules) } } type deps struct { // bootClasspath is the list of jars that form the boot classpath (generally the java.* and // android.* classes) for tools that still use it. javac targeting 1.9 or higher uses // systemModules and java9Classpath instead. bootClasspath classpath // classpath is the list of jars that form the classpath for javac and kotlinc rules. It // contains header jars for all static and non-static dependencies. classpath classpath // dexClasspath is the list of jars that form the classpath for d8 and r8 rules. It contains // header jars for all non-static dependencies. Static dependencies have already been // combined into the program jar. dexClasspath classpath // java9Classpath is the list of jars that will be added to the classpath when targeting // 1.9 or higher. It generally contains the android.* classes, while the java.* classes // are provided by systemModules. java9Classpath classpath processorPath classpath errorProneProcessorPath classpath processorClasses []string staticJars android.Paths staticHeaderJars android.Paths staticResourceJars android.Paths aidlIncludeDirs android.Paths srcs android.Paths srcJars android.Paths systemModules *systemModules aidlPreprocess android.OptionalPath kotlinStdlib android.Paths kotlinAnnotations android.Paths kotlinPlugins android.Paths aconfigProtoFiles android.Paths disableTurbine bool } func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) { for _, f := range dep.Srcs() { if f.Ext() != ".jar" { ctx.ModuleErrorf("genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency", ctx.OtherModuleName(dep.(blueprint.Module))) } } } func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext android.SdkContext) javaVersion { if javaVersion != "" { return normalizeJavaVersion(ctx, javaVersion) } else if ctx.Device() { return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx)) } else { return JAVA_VERSION_17 } } // Java version for stubs generation func getStubsJavaVersion() javaVersion { return JAVA_VERSION_8 } type javaVersion int const ( JAVA_VERSION_UNSUPPORTED = 0 JAVA_VERSION_6 = 6 JAVA_VERSION_7 = 7 JAVA_VERSION_8 = 8 JAVA_VERSION_9 = 9 JAVA_VERSION_11 = 11 JAVA_VERSION_17 = 17 ) func (v javaVersion) String() string { switch v { case JAVA_VERSION_6: // Java version 1.6 no longer supported, bumping to 1.8 return "1.8" case JAVA_VERSION_7: // Java version 1.7 no longer supported, bumping to 1.8 return "1.8" case JAVA_VERSION_8: return "1.8" case JAVA_VERSION_9: return "1.9" case JAVA_VERSION_11: return "11" case JAVA_VERSION_17: return "17" default: return "unsupported" } } func (v javaVersion) StringForKotlinc() string { // $ ./external/kotlinc/bin/kotlinc -jvm-target foo // error: unknown JVM target version: foo // Supported versions: 1.8, 9, 10, 11, 12, 13, 14, 15, 16, 17 switch v { case JAVA_VERSION_6: return "1.8" case JAVA_VERSION_7: return "1.8" case JAVA_VERSION_9: return "9" default: return v.String() } } // Returns true if javac targeting this version uses system modules instead of a bootclasspath. func (v javaVersion) usesJavaModules() bool { return v >= 9 } func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) javaVersion { switch javaVersion { case "1.6", "6": // Java version 1.6 no longer supported, bumping to 1.8 return JAVA_VERSION_8 case "1.7", "7": // Java version 1.7 no longer supported, bumping to 1.8 return JAVA_VERSION_8 case "1.8", "8": return JAVA_VERSION_8 case "1.9", "9": return JAVA_VERSION_9 case "11": return JAVA_VERSION_11 case "17": return JAVA_VERSION_17 case "10", "12", "13", "14", "15", "16": ctx.PropertyErrorf("java_version", "Java language level %s is not supported", javaVersion) return JAVA_VERSION_UNSUPPORTED default: ctx.PropertyErrorf("java_version", "Unrecognized Java language level") return JAVA_VERSION_UNSUPPORTED } } // // Java libraries (.jar file) // type Library struct { Module combinedExportedProguardFlagsFile android.Path InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.InstallPaths) } var _ android.ApexModule = (*Library)(nil) // Provides access to the list of permitted packages from apex boot jars. type PermittedPackagesForUpdatableBootJars interface { PermittedPackagesForUpdatableBootJars() []string } var _ PermittedPackagesForUpdatableBootJars = (*Library)(nil) func (j *Library) PermittedPackagesForUpdatableBootJars() []string { return j.properties.Permitted_packages } func shouldUncompressDex(ctx android.ModuleContext, libName string, dexpreopter *dexpreopter) bool { // Store uncompressed (and aligned) any dex files from jars in APEXes. if apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider); !apexInfo.IsForPlatform() { return true } // Store uncompressed (and do not strip) dex files from boot class path jars. if inList(ctx.ModuleName(), ctx.Config().BootJars()) { return true } // Store uncompressed dex files that are preopted on /system or /system_other. if !dexpreopter.dexpreoptDisabled(ctx, libName) { return true } if ctx.Config().UncompressPrivAppDex() && inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()) { return true } return false } // Sets `dexer.dexProperties.Uncompress_dex` to the proper value. func setUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter, dexer *dexer) { if dexer.dexProperties.Uncompress_dex == nil { // If the value was not force-set by the user, use reasonable default based on the module. dexer.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), dexpreopter)) } } // list of java_library modules that set platform_apis: true // this property is a no-op for java_library // TODO (b/215379393): Remove this allowlist var ( aospPlatformApiAllowlist = map[string]bool{ "adservices-test-scenarios": true, "aidl-cpp-java-test-interface-java": true, "aidl-test-extras-java": true, "aidl-test-interface-java": true, "aidl-test-interface-permission-java": true, "aidl_test_java_client_permission": true, "aidl_test_java_client_sdk1": true, "aidl_test_java_client_sdk29": true, "aidl_test_java_client": true, "aidl_test_java_service_permission": true, "aidl_test_java_service_sdk1": true, "aidl_test_java_service_sdk29": true, "aidl_test_java_service": true, "aidl_test_loggable_interface-java": true, "aidl_test_nonvintf_parcelable-V1-java": true, "aidl_test_nonvintf_parcelable-V2-java": true, "aidl_test_unstable_parcelable-java": true, "aidl_test_vintf_parcelable-V1-java": true, "aidl_test_vintf_parcelable-V2-java": true, "android.aidl.test.trunk-V1-java": true, "android.aidl.test.trunk-V2-java": true, "android.frameworks.location.altitude-V1-java": true, "android.frameworks.location.altitude-V2-java": true, "android.frameworks.stats-V1-java": true, "android.frameworks.stats-V2-java": true, "android.frameworks.stats-V3-java": true, "android.hardware.authsecret-V1-java": true, "android.hardware.authsecret-V2-java": true, "android.hardware.biometrics.common-V1-java": true, "android.hardware.biometrics.common-V2-java": true, "android.hardware.biometrics.common-V3-java": true, "android.hardware.biometrics.common-V4-java": true, "android.hardware.biometrics.face-V1-java": true, "android.hardware.biometrics.face-V2-java": true, "android.hardware.biometrics.face-V3-java": true, "android.hardware.biometrics.face-V4-java": true, "android.hardware.biometrics.fingerprint-V1-java": true, "android.hardware.biometrics.fingerprint-V2-java": true, "android.hardware.biometrics.fingerprint-V3-java": true, "android.hardware.biometrics.fingerprint-V4-java": true, "android.hardware.bluetooth.lmp_event-V1-java": true, "android.hardware.confirmationui-V1-java": true, "android.hardware.confirmationui-V2-java": true, "android.hardware.gatekeeper-V1-java": true, "android.hardware.gatekeeper-V2-java": true, "android.hardware.gnss-V1-java": true, "android.hardware.gnss-V2-java": true, "android.hardware.gnss-V3-java": true, "android.hardware.gnss-V4-java": true, "android.hardware.graphics.common-V1-java": true, "android.hardware.graphics.common-V2-java": true, "android.hardware.graphics.common-V3-java": true, "android.hardware.graphics.common-V4-java": true, "android.hardware.graphics.common-V5-java": true, "android.hardware.identity-V1-java": true, "android.hardware.identity-V2-java": true, "android.hardware.identity-V3-java": true, "android.hardware.identity-V4-java": true, "android.hardware.identity-V5-java": true, "android.hardware.identity-V6-java": true, "android.hardware.keymaster-V1-java": true, "android.hardware.keymaster-V2-java": true, "android.hardware.keymaster-V3-java": true, "android.hardware.keymaster-V4-java": true, "android.hardware.keymaster-V5-java": true, "android.hardware.oemlock-V1-java": true, "android.hardware.oemlock-V2-java": true, "android.hardware.power.stats-V1-java": true, "android.hardware.power.stats-V2-java": true, "android.hardware.power.stats-V3-java": true, "android.hardware.power-V1-java": true, "android.hardware.power-V2-java": true, "android.hardware.power-V3-java": true, "android.hardware.power-V4-java": true, "android.hardware.power-V5-java": true, "android.hardware.rebootescrow-V1-java": true, "android.hardware.rebootescrow-V2-java": true, "android.hardware.security.authgraph-V1-java": true, "android.hardware.security.keymint-V1-java": true, "android.hardware.security.keymint-V2-java": true, "android.hardware.security.keymint-V3-java": true, "android.hardware.security.keymint-V4-java": true, "android.hardware.security.secretkeeper-V1-java": true, "android.hardware.security.secureclock-V1-java": true, "android.hardware.security.secureclock-V2-java": true, "android.hardware.thermal-V1-java": true, "android.hardware.thermal-V2-java": true, "android.hardware.threadnetwork-V1-java": true, "android.hardware.weaver-V1-java": true, "android.hardware.weaver-V2-java": true, "android.hardware.weaver-V3-java": true, "android.security.attestationmanager-java": true, "android.security.authorization-java": true, "android.security.compat-java": true, "android.security.legacykeystore-java": true, "android.security.maintenance-java": true, "android.security.metrics-java": true, "android.system.keystore2-V1-java": true, "android.system.keystore2-V2-java": true, "android.system.keystore2-V3-java": true, "android.system.keystore2-V4-java": true, "binderReadParcelIface-java": true, "binderRecordReplayTestIface-java": true, "car-experimental-api-static-lib": true, "collector-device-lib-platform": true, "com.android.car.oem": true, "com.google.hardware.pixel.display-V10-java": true, "com.google.hardware.pixel.display-V1-java": true, "com.google.hardware.pixel.display-V2-java": true, "com.google.hardware.pixel.display-V3-java": true, "com.google.hardware.pixel.display-V4-java": true, "com.google.hardware.pixel.display-V5-java": true, "com.google.hardware.pixel.display-V6-java": true, "com.google.hardware.pixel.display-V7-java": true, "com.google.hardware.pixel.display-V8-java": true, "com.google.hardware.pixel.display-V9-java": true, "conscrypt-support": true, "cts-keystore-test-util": true, "cts-keystore-user-auth-helper-library": true, "ctsmediautil": true, "CtsNetTestsNonUpdatableLib": true, "DpmWrapper": true, "flickerlib-apphelpers": true, "flickerlib-helpers": true, "flickerlib-parsers": true, "flickerlib": true, "hardware.google.bluetooth.ccc-V1-java": true, "hardware.google.bluetooth.sar-V1-java": true, "monet": true, "pixel-power-ext-V1-java": true, "pixel-power-ext-V2-java": true, "pixel_stateresidency_provider_aidl_interface-java": true, "pixel-thermal-ext-V1-java": true, "protolog-lib": true, "RkpRegistrationCheck": true, "rotary-service-javastream-protos": true, "service_based_camera_extensions": true, "statsd-helper-test": true, "statsd-helper": true, "test-piece-2-V1-java": true, "test-piece-2-V2-java": true, "test-piece-3-V1-java": true, "test-piece-3-V2-java": true, "test-piece-3-V3-java": true, "test-piece-4-V1-java": true, "test-piece-4-V2-java": true, "test-root-package-V1-java": true, "test-root-package-V2-java": true, "test-root-package-V3-java": true, "test-root-package-V4-java": true, "testServiceIface-java": true, "wm-flicker-common-app-helpers": true, "wm-flicker-common-assertions": true, "wm-shell-flicker-utils": true, "wycheproof-keystore": true, } // Union of aosp and internal allowlists PlatformApiAllowlist = map[string]bool{} ) func init() { for k, v := range aospPlatformApiAllowlist { PlatformApiAllowlist[k] = v } } func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.provideHiddenAPIPropertyInfo(ctx) j.sdkVersion = j.SdkVersion(ctx) j.minSdkVersion = j.MinSdkVersion(ctx) j.maxSdkVersion = j.MaxSdkVersion(ctx) // SdkLibrary.GenerateAndroidBuildActions(ctx) sets the stubsLinkType to Unknown. // If the stubsLinkType has already been set to Unknown, the stubsLinkType should // not be overridden. if j.stubsLinkType != Unknown { if proptools.Bool(j.properties.Is_stubs_module) { j.stubsLinkType = Stubs } else { j.stubsLinkType = Implementation } } j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName()) proguardSpecInfo := j.collectProguardSpecInfo(ctx) android.SetProvider(ctx, ProguardSpecInfoProvider, proguardSpecInfo) exportedProguardFlagsFiles := proguardSpecInfo.ProguardFlagsFiles.ToList() j.extraProguardFlagsFiles = append(j.extraProguardFlagsFiles, exportedProguardFlagsFiles...) combinedExportedProguardFlagFile := android.PathForModuleOut(ctx, "export_proguard_flags") writeCombinedProguardFlagsFile(ctx, combinedExportedProguardFlagFile, exportedProguardFlagsFiles) j.combinedExportedProguardFlagsFile = combinedExportedProguardFlagFile apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) if !apexInfo.IsForPlatform() { j.hideApexVariantFromMake = true } j.checkSdkVersions(ctx) j.checkHeadersOnly(ctx) if ctx.Device() { j.dexpreopter.installPath = j.dexpreopter.getInstallPath( ctx, j.Name(), android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary setUncompressDex(ctx, &j.dexpreopter, &j.dexer) j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx) if j.usesLibrary.shouldDisableDexpreopt { j.dexpreopter.disableDexpreopt() } } j.compile(ctx, nil, nil, nil) exclusivelyForApex := !apexInfo.IsForPlatform() if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex { var extraInstallDeps android.InstallPaths if j.InstallMixin != nil { extraInstallDeps = j.InstallMixin(ctx, j.outputFile) } hostDexNeeded := Bool(j.deviceProperties.Hostdex) && !ctx.Host() if hostDexNeeded { j.hostdexInstallFile = ctx.InstallFile( android.PathForHostDexInstall(ctx, "framework"), j.Stem()+"-hostdex.jar", j.outputFile) } var installDir android.InstallPath if ctx.InstallInTestcases() { var archDir string if !ctx.Host() { archDir = ctx.DeviceConfig().DeviceArch() } installDir = android.PathForModuleInstall(ctx, ctx.ModuleName(), archDir) } else { installDir = android.PathForModuleInstall(ctx, "framework") } j.installFile = ctx.InstallFile(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...) } } func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { j.deps(ctx) j.usesLibrary.deps(ctx, false) } const ( aidlIncludeDir = "aidl" javaDir = "java" jarFileSuffix = ".jar" testConfigSuffix = "-AndroidTest.xml" ) // path to the jar file of a java library. Relative to / func sdkSnapshotFilePathForJar(_ android.SdkMemberContext, osPrefix, name string) string { return sdkSnapshotFilePathForMember(osPrefix, name, jarFileSuffix) } func sdkSnapshotFilePathForMember(osPrefix, name string, suffix string) string { return filepath.Join(javaDir, osPrefix, name+suffix) } type librarySdkMemberType struct { android.SdkMemberTypeBase // Function to retrieve the appropriate output jar (implementation or header) from // the library. jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path // Function to compute the snapshot relative path to which the named library's // jar should be copied. snapshotPathGetter func(ctx android.SdkMemberContext, osPrefix, name string) string // True if only the jar should be copied to the snapshot, false if the jar plus any additional // files like aidl files should also be copied. onlyCopyJarToSnapshot bool } const ( onlyCopyJarToSnapshot = true copyEverythingToSnapshot = false ) func (mt *librarySdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) { ctx.AddVariationDependencies(nil, dependencyTag, names...) } func (mt *librarySdkMemberType) IsInstance(module android.Module) bool { _, ok := module.(*Library) return ok } func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_import") } func (mt *librarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { return &librarySdkMemberProperties{} } type librarySdkMemberProperties struct { android.SdkMemberPropertiesBase JarToExport android.Path `android:"arch_variant"` AidlIncludeDirs android.Paths // The list of permitted packages that need to be passed to the prebuilts as they are used to // create the updatable-bcp-packages.txt file. PermittedPackages []string // The value of the min_sdk_version property, translated into a number where possible. MinSdkVersion *string `supported_build_releases:"Tiramisu+"` DexPreoptProfileGuided *bool `supported_build_releases:"UpsideDownCake+"` } func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { j := variant.(*Library) p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j) p.AidlIncludeDirs = j.AidlIncludeDirs() p.PermittedPackages = j.PermittedPackagesForUpdatableBootJars() // If the min_sdk_version was set then add the canonical representation of the API level to the // snapshot. if j.deviceProperties.Min_sdk_version != nil { canonical, err := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.String()) if err != nil { ctx.ModuleErrorf("%s", err) } p.MinSdkVersion = proptools.StringPtr(canonical) } if j.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided { p.DexPreoptProfileGuided = proptools.BoolPtr(true) } } func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { builder := ctx.SnapshotBuilder() memberType := ctx.MemberType().(*librarySdkMemberType) exportedJar := p.JarToExport if exportedJar != nil { // Delegate the creation of the snapshot relative path to the member type. snapshotRelativeJavaLibPath := memberType.snapshotPathGetter(ctx, p.OsPrefix(), ctx.Name()) // Copy the exported jar to the snapshot. builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath) propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) } if p.MinSdkVersion != nil { propertySet.AddProperty("min_sdk_version", *p.MinSdkVersion) } if len(p.PermittedPackages) > 0 { propertySet.AddProperty("permitted_packages", p.PermittedPackages) } dexPreoptSet := propertySet.AddPropertySet("dex_preopt") if p.DexPreoptProfileGuided != nil { dexPreoptSet.AddProperty("profile_guided", proptools.Bool(p.DexPreoptProfileGuided)) } // Do not copy anything else to the snapshot. if memberType.onlyCopyJarToSnapshot { return } aidlIncludeDirs := p.AidlIncludeDirs if len(aidlIncludeDirs) != 0 { sdkModuleContext := ctx.SdkModuleContext() for _, dir := range aidlIncludeDirs { // TODO(jiyong): copy parcelable declarations only aidlFiles, _ := sdkModuleContext.GlobWithDeps(dir.String()+"/**/*.aidl", nil) for _, file := range aidlFiles { builder.CopyToSnapshot(android.PathForSource(sdkModuleContext, file), filepath.Join(aidlIncludeDir, file)) } } // TODO(b/151933053) - add aidl include dirs property } } // java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well. // // By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were // compiled against the device bootclasspath. This jar is not suitable for installing on a device, but can be used // as a `static_libs` dependency of another module. // // Specifying `installable: true` will product a `.jar` file containing `classes.dex` files, suitable for installing on // a device. // // Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one // compiled against the host bootclasspath. func LibraryFactory() android.Module { module := &Library{} module.addHostAndDeviceProperties() module.initModuleAndImport(module) android.InitApexModule(module) InitJavaModule(module, android.HostAndDeviceSupported) return module } // java_library_static is an obsolete alias for java_library. func LibraryStaticFactory() android.Module { return LibraryFactory() } // java_library_host builds and links sources into a `.jar` file for the host. // // A java_library_host has a single variant that produces a `.jar` file containing `.class` files that were // compiled against the host bootclasspath. func LibraryHostFactory() android.Module { module := &Library{} module.addHostProperties() module.Module.properties.Installable = proptools.BoolPtr(true) android.InitApexModule(module) InitJavaModule(module, android.HostSupported) return module } // // Java Tests // // Test option struct. type TestOptions struct { android.CommonTestOptions // a list of extra test configuration files that should be installed with the module. Extra_test_configs []string `android:"path,arch_variant"` // Extra