summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/aar.go18
-rw-r--r--java/android_manifest.go31
-rw-r--r--java/androidmk.go25
-rwxr-xr-xjava/app.go134
-rw-r--r--java/app_test.go51
-rw-r--r--java/builder.go2
-rw-r--r--java/config/config.go14
-rw-r--r--java/dex.go12
-rw-r--r--java/dexpreopt_bootjars.go5
-rw-r--r--java/dexpreopt_config.go2
-rw-r--r--java/droiddoc.go10
-rw-r--r--java/java.go69
-rw-r--r--java/kotlin.go4
-rw-r--r--java/sdk.go330
-rw-r--r--java/sdk_library.go48
15 files changed, 569 insertions, 186 deletions
diff --git a/java/aar.go b/java/aar.go
index ae064e5b6..d707e36d7 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -15,11 +15,12 @@
package java
import (
- "android/soong/android"
"fmt"
"path/filepath"
"strings"
+ "android/soong/android"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -176,7 +177,10 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext,
linkDeps = append(linkDeps, assetFiles...)
// SDK version flags
- minSdkVersion := sdkVersionOrDefault(ctx, sdkContext.minSdkVersion())
+ minSdkVersion, err := sdkContext.minSdkVersion().effectiveVersionString(ctx)
+ if err != nil {
+ ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
+ }
linkFlags = append(linkFlags, "--min-sdk-version "+minSdkVersion)
linkFlags = append(linkFlags, "--target-sdk-version "+minSdkVersion)
@@ -523,22 +527,22 @@ type AARImport struct {
exportedStaticPackages android.Paths
}
-func (a *AARImport) sdkVersion() string {
- return String(a.properties.Sdk_version)
+func (a *AARImport) sdkVersion() sdkSpec {
+ return sdkSpecFrom(String(a.properties.Sdk_version))
}
func (a *AARImport) systemModules() string {
return ""
}
-func (a *AARImport) minSdkVersion() string {
+func (a *AARImport) minSdkVersion() sdkSpec {
if a.properties.Min_sdk_version != nil {
- return *a.properties.Min_sdk_version
+ return sdkSpecFrom(*a.properties.Min_sdk_version)
}
return a.sdkVersion()
}
-func (a *AARImport) targetSdkVersion() string {
+func (a *AARImport) targetSdkVersion() sdkSpec {
return a.sdkVersion()
}
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 021883e60..e3646f5f9 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -59,7 +59,7 @@ func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext
if isLibrary {
args = append(args, "--library")
} else {
- minSdkVersion, err := sdkVersionToNumber(ctx, sdkContext.minSdkVersion())
+ minSdkVersion, err := sdkContext.minSdkVersion().effectiveVersion(ctx)
if err != nil {
ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
}
@@ -92,17 +92,28 @@ func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext
}
var deps android.Paths
- targetSdkVersion := sdkVersionOrDefault(ctx, sdkContext.targetSdkVersion())
- if targetSdkVersion == ctx.Config().PlatformSdkCodename() &&
- ctx.Config().UnbundledBuild() &&
- !ctx.Config().UnbundledBuildUsePrebuiltSdks() &&
- ctx.Config().IsEnvTrue("UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT") {
- apiFingerprint := ApiFingerprintPath(ctx)
- targetSdkVersion += fmt.Sprintf(".$$(cat %s)", apiFingerprint.String())
- deps = append(deps, apiFingerprint)
+ targetSdkVersion, err := sdkContext.targetSdkVersion().effectiveVersionString(ctx)
+ if err != nil {
+ ctx.ModuleErrorf("invalid targetSdkVersion: %s", err)
+ }
+ if UseApiFingerprint(ctx, targetSdkVersion) {
+ targetSdkVersion += fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String())
+ deps = append(deps, ApiFingerprintPath(ctx))
+ }
+
+ minSdkVersion, err := sdkContext.minSdkVersion().effectiveVersionString(ctx)
+ if err != nil {
+ ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
+ }
+ if UseApiFingerprint(ctx, minSdkVersion) {
+ minSdkVersion += fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String())
+ deps = append(deps, ApiFingerprintPath(ctx))
}
fixedManifest := android.PathForModuleOut(ctx, "manifest_fixer", "AndroidManifest.xml")
+ if err != nil {
+ ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
+ }
ctx.Build(pctx, android.BuildParams{
Rule: manifestFixerRule,
Description: "fix manifest",
@@ -110,7 +121,7 @@ func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext
Implicits: deps,
Output: fixedManifest,
Args: map[string]string{
- "minSdkVersion": sdkVersionOrDefault(ctx, sdkContext.minSdkVersion()),
+ "minSdkVersion": minSdkVersion,
"targetSdkVersion": targetSdkVersion,
"args": strings.Join(args, " "),
},
diff --git a/java/androidmk.go b/java/androidmk.go
index 04bf15cf4..6d4d40bf6 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -93,7 +93,7 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
if len(library.dexpreopter.builtInstalled) > 0 {
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", library.dexpreopter.builtInstalled)
}
- entries.SetString("LOCAL_SDK_VERSION", library.sdkVersion())
+ entries.SetString("LOCAL_SDK_VERSION", library.sdkVersion().raw)
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", library.implementationAndResourcesJar)
entries.SetPath("LOCAL_SOONG_HEADER_JAR", library.headerJarFile)
@@ -174,7 +174,7 @@ func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !Bool(prebuilt.properties.Installable))
entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.combinedClasspathFile)
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.combinedClasspathFile)
- entries.SetString("LOCAL_SDK_VERSION", prebuilt.sdkVersion())
+ entries.SetString("LOCAL_SDK_VERSION", prebuilt.sdkVersion().raw)
entries.SetString("LOCAL_MODULE_STEM", prebuilt.Stem())
},
},
@@ -223,7 +223,7 @@ func (prebuilt *AARImport) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetPath("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", prebuilt.proguardFlags)
entries.SetPath("LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES", prebuilt.extraAaptPackagesFile)
entries.SetPath("LOCAL_FULL_MANIFEST_FILE", prebuilt.manifest)
- entries.SetString("LOCAL_SDK_VERSION", prebuilt.sdkVersion())
+ entries.SetString("LOCAL_SDK_VERSION", prebuilt.sdkVersion().raw)
},
},
}}
@@ -663,11 +663,7 @@ func (a *AndroidAppImport) AndroidMkEntries() []android.AndroidMkEntries {
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(entries *android.AndroidMkEntries) {
entries.SetBoolIfTrue("LOCAL_PRIVILEGED_MODULE", a.Privileged())
- if a.certificate != nil {
- entries.SetPath("LOCAL_CERTIFICATE", a.certificate.Pem)
- } else {
- entries.SetString("LOCAL_CERTIFICATE", "PRESIGNED")
- }
+ entries.SetString("LOCAL_CERTIFICATE", a.certificate.AndroidMkString())
entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", a.properties.Overrides...)
if len(a.dexpreopter.builtInstalled) > 0 {
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", a.dexpreopter.builtInstalled)
@@ -695,3 +691,16 @@ func androidMkWriteTestData(data android.Paths, entries *android.AndroidMkEntrie
}
entries.AddStrings("LOCAL_COMPATIBILITY_SUPPORT_FILES", testFiles...)
}
+
+func (r *RuntimeResourceOverlay) AndroidMkEntries() []android.AndroidMkEntries {
+ return []android.AndroidMkEntries{android.AndroidMkEntries{
+ Class: "ETC",
+ OutputFile: android.OptionalPathForPath(r.outputFile),
+ Include: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(entries *android.AndroidMkEntries) {
+ entries.SetPath("LOCAL_MODULE_PATH", r.installDir.ToMakePath())
+ },
+ },
+ }}
+}
diff --git a/java/app.go b/java/app.go
index e9941f2d2..a27996c14 100755
--- a/java/app.go
+++ b/java/app.go
@@ -47,6 +47,7 @@ func RegisterAppBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
ctx.RegisterModuleType("android_app_import", AndroidAppImportFactory)
ctx.RegisterModuleType("android_test_import", AndroidTestImportFactory)
+ ctx.RegisterModuleType("runtime_resource_overlay", RuntimeResourceOverlayFactory)
}
// AndroidManifest.xml merging
@@ -153,16 +154,31 @@ func (a *AndroidApp) OutputFile() android.Path {
return a.outputFile
}
+func (a *AndroidApp) Certificate() Certificate {
+ return a.certificate
+}
+
var _ AndroidLibraryDependency = (*AndroidApp)(nil)
type Certificate struct {
- Pem, Key android.Path
+ Pem, Key android.Path
+ presigned bool
+}
+
+var presignedCertificate = Certificate{presigned: true}
+
+func (c Certificate) AndroidMkString() string {
+ if c.presigned {
+ return "PRESIGNED"
+ } else {
+ return c.Pem.String()
+ }
}
func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
a.Module.deps(ctx)
- if String(a.appProperties.Stl) == "c++_shared" && a.sdkVersion() == "" {
+ if String(a.appProperties.Stl) == "c++_shared" && !a.sdkVersion().specified() {
ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
}
@@ -211,7 +227,7 @@ func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Returns true if the native libraries should be stored in the APK uncompressed and the
// extractNativeLibs application flag should be set to false in the manifest.
func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
- minSdkVersion, err := sdkVersionToNumber(ctx, a.minSdkVersion())
+ minSdkVersion, err := a.minSdkVersion().effectiveVersion(ctx)
if err != nil {
ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.minSdkVersion(), err)
}
@@ -404,12 +420,15 @@ func processMainCert(m android.ModuleBase, certPropValue string, certificates []
if certPropValue != "" {
defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
mainCert = Certificate{
- defaultDir.Join(ctx, certPropValue+".x509.pem"),
- defaultDir.Join(ctx, certPropValue+".pk8"),
+ Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
+ Key: defaultDir.Join(ctx, certPropValue+".pk8"),
}
} else {
pem, key := ctx.Config().DefaultAppCertificate(ctx)
- mainCert = Certificate{pem, key}
+ mainCert = Certificate{
+ Pem: pem,
+ Key: key,
+ }
}
certificates = append([]Certificate{mainCert}, certificates...)
}
@@ -797,8 +816,8 @@ func AndroidAppCertificateFactory() android.Module {
func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
cert := String(c.properties.Certificate)
c.Certificate = Certificate{
- android.PathForModuleSrc(ctx, cert+".x509.pem"),
- android.PathForModuleSrc(ctx, cert+".pk8"),
+ Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
+ Key: android.PathForModuleSrc(ctx, cert+".pk8"),
}
}
@@ -855,7 +874,7 @@ type AndroidAppImport struct {
archVariants interface{}
outputFile android.Path
- certificate *Certificate
+ certificate Certificate
dexpreopter
@@ -1063,7 +1082,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
if len(certificates) != 1 {
ctx.ModuleErrorf("Unexpected number of certificates were extracted: %q", certificates)
}
- a.certificate = &certificates[0]
+ a.certificate = certificates[0]
signed := android.PathForModuleOut(ctx, "signed", ctx.ModuleName()+".apk")
SignAppPackage(ctx, signed, dexOutput, certificates)
a.outputFile = signed
@@ -1071,6 +1090,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
alignedApk := android.PathForModuleOut(ctx, "zip-aligned", ctx.ModuleName()+".apk")
TransformZipAlign(ctx, alignedApk, dexOutput)
a.outputFile = alignedApk
+ a.certificate = presignedCertificate
}
// TODO: Optionally compress the output apk.
@@ -1097,6 +1117,10 @@ func (a *AndroidAppImport) JacocoReportClassesFile() android.Path {
return nil
}
+func (a *AndroidAppImport) Certificate() Certificate {
+ return a.certificate
+}
+
var dpiVariantGroupType reflect.Type
var archVariantGroupType reflect.Type
@@ -1212,6 +1236,96 @@ func AndroidTestImportFactory() android.Module {
return module
}
+type RuntimeResourceOverlay struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+ aapt
+
+ properties RuntimeResourceOverlayProperties
+
+ outputFile android.Path
+ installDir android.InstallPath
+}
+
+type RuntimeResourceOverlayProperties struct {
+ // the name of a certificate in the default certificate directory or an android_app_certificate
+ // module name in the form ":module".
+ Certificate *string
+
+ // optional theme name. If specified, the overlay package will be applied
+ // only when the ro.boot.vendor.overlay.theme system property is set to the same value.
+ Theme *string
+
+ // if not blank, set to the version of the sdk to compile against.
+ // Defaults to compiling against the current platform.
+ Sdk_version *string
+
+ // if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
+ // Defaults to sdk_version if not set.
+ Min_sdk_version *string
+}
+
+func (r *RuntimeResourceOverlay) DepsMutator(ctx android.BottomUpMutatorContext) {
+ sdkDep := decodeSdkDep(ctx, sdkContext(r))
+ if sdkDep.hasFrameworkLibs() {
+ r.aapt.deps(ctx, sdkDep)
+ }
+
+ cert := android.SrcIsModule(String(r.properties.Certificate))
+ if cert != "" {
+ ctx.AddDependency(ctx.Module(), certificateTag, cert)
+ }
+}
+
+func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ // Compile and link resources
+ r.aapt.hasNoCode = true
+ // Do not remove resources without default values nor dedupe resource configurations with the same value
+ r.aapt.buildActions(ctx, r, "--no-resource-deduping", "--no-resource-removal")
+
+ // Sign the built package
+ _, certificates := collectAppDeps(ctx, false)
+ certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx)
+ signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk")
+ SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates)
+
+ r.outputFile = signed
+ r.installDir = android.PathForModuleInstall(ctx, "overlay", String(r.properties.Theme))
+ ctx.InstallFile(r.installDir, r.outputFile.Base(), r.outputFile)
+}
+
+func (r *RuntimeResourceOverlay) sdkVersion() sdkSpec {
+ return sdkSpecFrom(String(r.properties.Sdk_version))
+}
+
+func (r *RuntimeResourceOverlay) systemModules() string {
+ return ""
+}
+
+func (r *RuntimeResourceOverlay) minSdkVersion() sdkSpec {
+ if r.properties.Min_sdk_version != nil {
+ return sdkSpecFrom(*r.properties.Min_sdk_version)
+ }
+ return r.sdkVersion()
+}
+
+func (r *RuntimeResourceOverlay) targetSdkVersion() sdkSpec {
+ return r.sdkVersion()
+}
+
+// runtime_resource_overlay generates a resource-only apk file that can overlay application and
+// system resources at run time.
+func RuntimeResourceOverlayFactory() android.Module {
+ module := &RuntimeResourceOverlay{}
+ module.AddProperties(
+ &module.properties,
+ &module.aaptProperties)
+
+ InitJavaModule(module, android.DeviceSupported)
+
+ return module
+}
+
type UsesLibraryProperties struct {
// A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
Uses_libs []string
diff --git a/java/app_test.go b/java/app_test.go
index 6f89da410..2682682cf 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2207,3 +2207,54 @@ func checkAapt2LinkFlag(t *testing.T, aapt2Flags, flagName, expectedValue string
}
}
}
+
+func TestRuntimeResourceOverlay(t *testing.T) {
+ ctx, config := testJava(t, `
+ runtime_resource_overlay {
+ name: "foo",
+ certificate: "platform",
+ product_specific: true,
+ aaptflags: ["--keep-raw-values"],
+ }
+
+ runtime_resource_overlay {
+ name: "foo_themed",
+ certificate: "platform",
+ product_specific: true,
+ theme: "faza",
+ }
+ `)
+
+ m := ctx.ModuleForTests("foo", "android_common")
+
+ // Check AAPT2 link flags.
+ aapt2Flags := m.Output("package-res.apk").Args["flags"]
+ expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
+ absentFlags := android.RemoveListFromList(expectedFlags, strings.Split(aapt2Flags, " "))
+ if len(absentFlags) > 0 {
+ t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
+ }
+
+ // Check cert signing flag.
+ signedApk := m.Output("signed/foo.apk")
+ signingFlag := signedApk.Args["certificates"]
+ expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
+ if expected != signingFlag {
+ t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
+ }
+
+ // Check device location.
+ path := android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
+ expectedPath := []string{"/tmp/target/product/test_device/product/overlay"}
+ if !reflect.DeepEqual(path, expectedPath) {
+ t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
+ }
+
+ // A themed module has a different device location
+ m = ctx.ModuleForTests("foo_themed", "android_common")
+ path = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
+ expectedPath = []string{"/tmp/target/product/test_device/product/overlay/faza"}
+ if !reflect.DeepEqual(path, expectedPath) {
+ t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
+ }
+}
diff --git a/java/builder.go b/java/builder.go
index 26a49ea53..f9b53674d 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -38,7 +38,7 @@ var (
// this, all java rules write into separate directories and then are combined into a .jar file
// (if the rule produces .class files) or a .srcjar file (if the rule produces .java files).
// .srcjar files are unzipped into a temporary directory when compiled with javac.
- javac = pctx.AndroidRemoteStaticRule("javac", android.SUPPORTS_GOMA,
+ javac = pctx.AndroidRemoteStaticRule("javac", android.RemoteRuleSupports{Goma: true, RBE: true, RBEFlag: android.RBE_JAVAC},
blueprint.RuleParams{
Command: `rm -rf "$outDir" "$annoDir" "$srcJarDir" && mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` +
`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
diff --git a/java/config/config.go b/java/config/config.go
index 6da7279c3..7f446e5db 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -148,6 +148,20 @@ func init() {
return ""
})
+ pctx.VariableFunc("R8Wrapper", func(ctx android.PackageVarContext) string {
+ if override := ctx.Config().Getenv("R8_WRAPPER"); override != "" {
+ return override + " "
+ }
+ return ""
+ })
+
+ pctx.VariableFunc("D8Wrapper", func(ctx android.PackageVarContext) string {
+ if override := ctx.Config().Getenv("D8_WRAPPER"); override != "" {
+ return override + " "
+ }
+ return ""
+ })
+
pctx.HostJavaToolVariable("JacocoCLIJar", "jacoco-cli.jar")
pctx.HostBinToolVariable("ManifestCheckCmd", "manifest_check")
diff --git a/java/dex.go b/java/dex.go
index cd6d90de6..6afdb6dc4 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -22,10 +22,10 @@ import (
"android/soong/android"
)
-var d8 = pctx.AndroidStaticRule("d8",
+var d8 = pctx.AndroidRemoteStaticRule("d8", android.RemoteRuleSupports{RBE: true, RBEFlag: android.RBE_D8},
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
- `${config.D8Cmd} ${config.DexFlags} --output $outDir $d8Flags $in && ` +
+ `${config.D8Wrapper}${config.D8Cmd} ${config.DexFlags} --output $outDir $d8Flags $in && ` +
`${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
`${config.MergeZipsCmd} -D -stripFile "**/*.class" $out $outDir/classes.dex.jar $in`,
CommandDeps: []string{
@@ -36,11 +36,11 @@ var d8 = pctx.AndroidStaticRule("d8",
},
"outDir", "d8Flags", "zipFlags")
-var r8 = pctx.AndroidStaticRule("r8",
+var r8 = pctx.AndroidRemoteStaticRule("r8", android.RemoteRuleSupports{RBE: true, RBEFlag: android.RBE_R8},
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
`rm -f "$outDict" && ` +
- `${config.R8Cmd} ${config.DexFlags} -injars $in --output $outDir ` +
+ `${config.R8Wrapper}${config.R8Cmd} ${config.DexFlags} -injars $in --output $outDir ` +
`--force-proguard-compatibility ` +
`--no-data-resources ` +
`-printmapping $outDict ` +
@@ -73,12 +73,12 @@ func (j *Module) dexCommonFlags(ctx android.ModuleContext) []string {
"--verbose")
}
- minSdkVersion, err := sdkVersionToNumberAsString(ctx, j.minSdkVersion())
+ minSdkVersion, err := j.minSdkVersion().effectiveVersion(ctx)
if err != nil {
ctx.PropertyErrorf("min_sdk_version", "%s", err)
}
- flags = append(flags, "--min-api "+minSdkVersion)
+ flags = append(flags, "--min-api "+minSdkVersion.asNumberString())
return flags
}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index c6aa7fe0d..87f6d5e33 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -88,6 +88,9 @@ type bootImageConfig struct {
images map[android.ArchType]android.OutputPath // first image file
imagesDeps map[android.ArchType]android.OutputPaths // all files
+ // Only for extensions, paths to the primary boot images (grouped by target).
+ primaryImages map[android.ArchType]android.OutputPath
+
// File path to a zip archive with all image files (or nil, if not needed).
zip android.WritablePath
}
@@ -355,7 +358,7 @@ func buildBootImageRuleForArch(ctx android.SingletonContext, image *bootImage,
}
if image.extension {
- artImage := artBootImageConfig(ctx).images[arch]
+ artImage := image.primaryImages[arch]
cmd.
Flag("--runtime-arg").FlagWithInputList("-Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", image.dexLocationsDeps, ":").
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 31bec93eb..637a32f0a 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -246,10 +246,12 @@ func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig {
// specific to the framework config
frameworkCfg.dexPathsDeps = append(artCfg.dexPathsDeps, frameworkCfg.dexPathsDeps...)
+ frameworkCfg.primaryImages = artCfg.images
frameworkCfg.imageLocations = append(artCfg.imageLocations, frameworkCfg.imageLocations...)
// specific to the jitzygote-framework config
frameworkJZCfg.dexPathsDeps = append(artJZCfg.dexPathsDeps, frameworkJZCfg.dexPathsDeps...)
+ frameworkJZCfg.primaryImages = artJZCfg.images
frameworkJZCfg.imageLocations = append(artJZCfg.imageLocations, frameworkJZCfg.imageLocations...)
return configs
diff --git a/java/droiddoc.go b/java/droiddoc.go
index f62f5f901..abdceba33 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -424,19 +424,19 @@ func JavadocHostFactory() android.Module {
var _ android.OutputFileProducer = (*Javadoc)(nil)
-func (j *Javadoc) sdkVersion() string {
- return String(j.properties.Sdk_version)
+func (j *Javadoc) sdkVersion() sdkSpec {
+ return sdkSpecFrom(String(j.properties.Sdk_version))
}
func (j *Javadoc) systemModules() string {
return proptools.String(j.properties.System_modules)
}
-func (j *Javadoc) minSdkVersion() string {
+func (j *Javadoc) minSdkVersion() sdkSpec {
return j.sdkVersion()
}
-func (j *Javadoc) targetSdkVersion() string {
+func (j *Javadoc) targetSdkVersion() sdkSpec {
return j.sdkVersion()
}
@@ -1456,6 +1456,8 @@ func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleB
func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
+ // Metalava uses lots of memory, restrict the number of metalava jobs that can run in parallel.
+ rule.HighMem()
cmd := rule.Command().BuiltTool(ctx, "metalava").
Flag(config.JavacVmFlags).
FlagWithArg("-encoding ", "UTF-8").
diff --git a/java/java.go b/java/java.go
index 4c6a5a5ac..ed3dca9e0 100644
--- a/java/java.go
+++ b/java/java.go
@@ -87,7 +87,7 @@ func (j *Module) checkSdkVersion(ctx android.ModuleContext) {
if j.SocSpecific() || j.DeviceSpecific() ||
(j.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
if sc, ok := ctx.Module().(sdkContext); ok {
- if sc.sdkVersion() == "" {
+ if !sc.sdkVersion().specified() {
ctx.PropertyErrorf("sdk_version",
"sdk_version must have a value when the module is located at vendor or product(only if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is set).")
}
@@ -98,12 +98,11 @@ func (j *Module) checkSdkVersion(ctx android.ModuleContext) {
func (j *Module) checkPlatformAPI(ctx android.ModuleContext) {
if sc, ok := ctx.Module().(sdkContext); ok {
usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis)
- if usePlatformAPI != (sc.sdkVersion() == "") {
- if usePlatformAPI {
- ctx.PropertyErrorf("platform_apis", "platform_apis must be false when sdk_version is not empty.")
- } else {
- ctx.PropertyErrorf("platform_apis", "platform_apis must be true when sdk_version is empty.")
- }
+ sdkVersionSpecified := sc.sdkVersion().specified()
+ if usePlatformAPI && sdkVersionSpecified {
+ ctx.PropertyErrorf("platform_apis", "platform_apis must be false when sdk_version is not empty.")
+ } else if !usePlatformAPI && !sdkVersionSpecified {
+ ctx.PropertyErrorf("platform_apis", "platform_apis must be true when sdk_version is empty.")
}
}
@@ -451,8 +450,8 @@ type Dependency interface {
}
type SdkLibraryDependency interface {
- SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion string) android.Paths
- SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion string) android.Paths
+ SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths
+ SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths
}
type xref interface {
@@ -553,24 +552,24 @@ func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool {
ctx.Config().UnbundledBuild())
}
-func (j *Module) sdkVersion() string {
- return String(j.deviceProperties.Sdk_version)
+func (j *Module) sdkVersion() sdkSpec {
+ return sdkSpecFrom(String(j.deviceProperties.Sdk_version))
}
func (j *Module) systemModules() string {
return proptools.String(j.deviceProperties.System_modules)
}
-func (j *Module) minSdkVersion() string {
+func (j *Module) minSdkVersion() sdkSpec {
if j.deviceProperties.Min_sdk_version != nil {
- return *j.deviceProperties.Min_sdk_version
+ return sdkSpecFrom(*j.deviceProperties.Min_sdk_version)
}
return j.sdkVersion()
}
-func (j *Module) targetSdkVersion() string {
+func (j *Module) targetSdkVersion() sdkSpec {
if j.deviceProperties.Target_sdk_version != nil {
- return *j.deviceProperties.Target_sdk_version
+ return sdkSpecFrom(*j.deviceProperties.Target_sdk_version)
}
return j.sdkVersion()
}
@@ -776,26 +775,25 @@ func (m *Module) getLinkType(name string) (ret linkType, stubs bool) {
name == "stub-annotations" || name == "private-stub-annotations-jar" ||
name == "core-lambda-stubs" || name == "core-generated-annotation-stubs":
return javaCore, true
- case ver == "core_current":
+ case ver.kind == sdkCore:
return javaCore, false
case name == "android_system_stubs_current":
return javaSystem, true
- case strings.HasPrefix(ver, "system_"):
+ case ver.kind == sdkSystem:
return javaSystem, false
case name == "android_test_stubs_current":
return javaSystem, true
- case strings.HasPrefix(ver, "test_"):
+ case ver.kind == sdkTest:
return javaPlatform, false
case name == "android_stubs_current":
return javaSdk, true
- case ver == "current":
+ case ver.kind == sdkPublic:
return javaSdk, false
- case ver == "" || ver == "none" || ver == "core_platform":
+ case ver.kind == sdkPrivate || ver.kind == sdkNone || ver.kind == sdkCorePlatform:
return javaPlatform, false
+ case !ver.valid():
+ panic(fmt.Errorf("sdk_version is invalid. got %q", ver.raw))
default:
- if _, err := strconv.Atoi(ver); err != nil {
- panic(fmt.Errorf("expected sdk_version to be a number, got %q", ver))
- }
return javaSdk, false
}
}
@@ -992,19 +990,7 @@ func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) {
}
func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) javaVersion {
- v := sdkContext.sdkVersion()
- // For PDK builds, use the latest SDK version instead of "current"
- if ctx.Config().IsPdkBuild() &&
- (v == "" || v == "none" || v == "core_platform" || v == "current") {
- sdkVersions := ctx.Config().Get(sdkVersionsKey).([]int)
- latestSdkVersion := 0
- if len(sdkVersions) > 0 {
- latestSdkVersion = sdkVersions[len(sdkVersions)-1]
- }
- v = strconv.Itoa(latestSdkVersion)
- }
-
- sdk, err := sdkVersionToNumber(ctx, v)
+ sdk, err := sdkContext.sdkVersion().effectiveVersion(ctx)
if err != nil {
ctx.PropertyErrorf("sdk_version", "%s", err)
}
@@ -1741,6 +1727,11 @@ type Library struct {
}
func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool {
+ // Store uncompressed (and aligned) any dex files from jars in APEXes.
+ if am, ok := ctx.Module().(android.ApexModule); ok && !am.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
@@ -2282,11 +2273,11 @@ type Import struct {
exportedSdkLibs []string
}
-func (j *Import) sdkVersion() string {
- return String(j.properties.Sdk_version)
+func (j *Import) sdkVersion() sdkSpec {
+ return sdkSpecFrom(String(j.properties.Sdk_version))
}
-func (j *Import) minSdkVersion() string {
+func (j *Import) minSdkVersion() sdkSpec {
return j.sdkVersion()
}
diff --git a/java/kotlin.go b/java/kotlin.go
index 5319a4ff9..cb7da20f8 100644
--- a/java/kotlin.go
+++ b/java/kotlin.go
@@ -26,7 +26,7 @@ import (
"github.com/google/blueprint"
)
-var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.SUPPORTS_GOMA,
+var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports{Goma: true},
blueprint.RuleParams{
Command: `rm -rf "$classesDir" "$srcJarDir" "$kotlinBuildFile" "$emptyDir" && ` +
`mkdir -p "$classesDir" "$srcJarDir" "$emptyDir" && ` +
@@ -88,7 +88,7 @@ func kotlinCompile(ctx android.ModuleContext, outputFile android.WritablePath,
})
}
-var kapt = pctx.AndroidRemoteStaticRule("kapt", android.SUPPORTS_GOMA,
+var kapt = pctx.AndroidRemoteStaticRule("kapt", android.RemoteRuleSupports{Goma: true},
blueprint.RuleParams{
Command: `rm -rf "$srcJarDir" "$kotlinBuildFile" "$kaptDir" && mkdir -p "$srcJarDir" "$kaptDir" && ` +
`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
diff --git a/java/sdk.go b/java/sdk.go
index 66eb284ba..f388358e5 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -15,14 +15,15 @@
package java
import (
- "android/soong/android"
- "android/soong/java/config"
"fmt"
"path/filepath"
"sort"
"strconv"
"strings"
+ "android/soong/android"
+ "android/soong/java/config"
+
"github.com/google/blueprint/pathtools"
)
@@ -37,83 +38,258 @@ var sdkFrameworkAidlPathKey = android.NewOnceKey("sdkFrameworkAidlPathKey")
var apiFingerprintPathKey = android.NewOnceKey("apiFingerprintPathKey")
type sdkContext interface {
- // sdkVersion returns the sdk_version property of the current module, or an empty string if it is not set.
- sdkVersion() string
+ // sdkVersion returns sdkSpec that corresponds to the sdk_version property of the current module
+ sdkVersion() sdkSpec
// systemModules returns the system_modules property of the current module, or an empty string if it is not set.
systemModules() string
- // minSdkVersion returns the min_sdk_version property of the current module, or sdkVersion() if it is not set.
- minSdkVersion() string
- // targetSdkVersion returns the target_sdk_version property of the current module, or sdkVersion() if it is not set.
- targetSdkVersion() string
+ // minSdkVersion returns sdkSpec that corresponds to the min_sdk_version property of the current module,
+ // or from sdk_version if it is not set.
+ minSdkVersion() sdkSpec
+ // targetSdkVersion returns the sdkSpec that corresponds to the target_sdk_version property of the current module,
+ // or from sdk_version if it is not set.
+ targetSdkVersion() sdkSpec
}
-func sdkVersionOrDefault(ctx android.BaseModuleContext, v string) string {
- switch v {
- case "", "none", "current", "test_current", "system_current", "core_current", "core_platform":
- return ctx.Config().DefaultAppTargetSdk()
- default:
- return v
+func UseApiFingerprint(ctx android.BaseModuleContext, v string) bool {
+ if v == ctx.Config().PlatformSdkCodename() &&
+ ctx.Config().UnbundledBuild() &&
+ !ctx.Config().UnbundledBuildUsePrebuiltSdks() &&
+ ctx.Config().IsEnvTrue("UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT") {
+ return true
}
+ return false
}
-// Returns a sdk version as a number. For modules targeting an unreleased SDK (meaning it does not yet have a number)
-// it returns android.FutureApiLevel (10000).
-func sdkVersionToNumber(ctx android.EarlyModuleContext, v string) (int, error) {
- switch v {
- case "", "none", "current", "test_current", "system_current", "core_current", "core_platform":
- return ctx.Config().DefaultAppTargetSdkInt(), nil
+// sdkKind represents a particular category of an SDK spec like public, system, test, etc.
+type sdkKind int
+
+const (
+ sdkInvalid sdkKind = iota
+ sdkNone
+ sdkCore
+ sdkCorePlatform
+ sdkPublic
+ sdkSystem
+ sdkTest
+ sdkPrivate
+)
+
+// String returns the string representation of this sdkKind
+func (k sdkKind) String() string {
+ switch k {
+ case sdkPrivate:
+ return "private"
+ case sdkNone:
+ return "none"
+ case sdkPublic:
+ return "public"
+ case sdkSystem:
+ return "system"
+ case sdkTest:
+ return "test"
+ case sdkCore:
+ return "core"
+ case sdkCorePlatform:
+ return "core_platform"
default:
- n := android.GetNumericSdkVersion(v)
- if i, err := strconv.Atoi(n); err != nil {
- return -1, fmt.Errorf("invalid sdk version %q", n)
- } else {
- return i, nil
- }
+ return "invalid"
}
}
-func sdkVersionToNumberAsString(ctx android.EarlyModuleContext, v string) (string, error) {
- n, err := sdkVersionToNumber(ctx, v)
- if err != nil {
- return "", err
+// sdkVersion represents a specific version number of an SDK spec of a particular kind
+type sdkVersion int
+
+const (
+ // special version number for a not-yet-frozen SDK
+ sdkVersionCurrent sdkVersion = sdkVersion(android.FutureApiLevel)
+ // special version number to be used for SDK specs where version number doesn't
+ // make sense, e.g. "none", "", etc.
+ sdkVersionNone sdkVersion = sdkVersion(0)
+)
+
+// isCurrent checks if the sdkVersion refers to the not-yet-published version of an sdkKind
+func (v sdkVersion) isCurrent() bool {
+ return v == sdkVersionCurrent
+}
+
+// isNumbered checks if the sdkVersion refers to the published (a.k.a numbered) version of an sdkKind
+func (v sdkVersion) isNumbered() bool {
+ return !v.isCurrent() && v != sdkVersionNone
+}
+
+// String returns the string representation of this sdkVersion.
+func (v sdkVersion) String() string {
+ if v.isCurrent() {
+ return "current"
+ } else if v.isNumbered() {
+ return strconv.Itoa(int(v))
}
- return strconv.Itoa(n), nil
+ return "(no version)"
}
-func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext sdkContext) sdkDep {
- v := sdkContext.sdkVersion()
-
- // For PDK builds, use the latest SDK version instead of "current"
- if ctx.Config().IsPdkBuild() && (v == "" || v == "current") {
- sdkVersions := ctx.Config().Get(sdkVersionsKey).([]int)
- latestSdkVersion := 0
- if len(sdkVersions) > 0 {
- latestSdkVersion = sdkVersions[len(sdkVersions)-1]
+// asNumberString directly converts the numeric value of this sdk version as a string.
+// When isNumbered() is true, this method is the same as String(). However, for sdkVersionCurrent
+// and sdkVersionNone, this returns 10000 and 0 while String() returns "current" and "(no version"),
+// respectively.
+func (v sdkVersion) asNumberString() string {
+ return strconv.Itoa(int(v))
+}
+
+// sdkSpec represents the kind and the version of an SDK for a module to build against
+type sdkSpec struct {
+ kind sdkKind
+ version sdkVersion
+ raw string
+}
+
+// valid checks if this sdkSpec is well-formed. Note however that true doesn't mean that the
+// specified SDK actually exists.
+func (s sdkSpec) valid() bool {
+ return s.kind != sdkInvalid
+}
+
+// specified checks if this sdkSpec is well-formed and is not "".
+func (s sdkSpec) specified() bool {
+ return s.valid() && s.kind != sdkPrivate
+}
+
+// prebuiltSdkAvailableForUnbundledBuilt tells whether this sdkSpec can have a prebuilt SDK
+// that can be used for unbundled builds.
+func (s sdkSpec) prebuiltSdkAvailableForUnbundledBuild() bool {
+ // "", "none", and "core_platform" are not available for unbundled build
+ // as we don't/can't have prebuilt stub for the versions
+ return s.kind != sdkPrivate && s.kind != sdkNone && s.kind != sdkCorePlatform
+}
+
+// forPdkBuild converts this sdkSpec into another sdkSpec that is for the PDK builds.
+func (s sdkSpec) forPdkBuild(ctx android.EarlyModuleContext) sdkSpec {
+ // For PDK builds, use the latest SDK version instead of "current" or ""
+ if s.kind == sdkPrivate || s.kind == sdkPublic {
+ kind := s.kind
+ if kind == sdkPrivate {
+ // We don't have prebuilt SDK for private APIs, so use the public SDK
+ // instead. This looks odd, but that's how it has been done.
+ // TODO(b/148271073): investigate the need for this.
+ kind = sdkPublic
}
- v = strconv.Itoa(latestSdkVersion)
+ version := sdkVersion(LatestSdkVersionInt(ctx))
+ return sdkSpec{kind, version, s.raw}
}
+ return s
+}
- numericSdkVersion, err := sdkVersionToNumber(ctx, v)
- if err != nil {
- ctx.PropertyErrorf("sdk_version", "%s", err)
- return sdkDep{}
+// usePrebuilt determines whether prebuilt SDK should be used for this sdkSpec with the given context.
+func (s sdkSpec) usePrebuilt(ctx android.EarlyModuleContext) bool {
+ if s.version.isCurrent() {
+ // "current" can be built from source and be from prebuilt SDK
+ return ctx.Config().UnbundledBuildUsePrebuiltSdks()
+ } else if s.version.isNumbered() {
+ // sanity check
+ if s.kind != sdkPublic && s.kind != sdkSystem && s.kind != sdkTest {
+ panic(fmt.Errorf("prebuilt SDK is not not available for sdkKind=%q", s.kind))
+ return false
+ }
+ // numbered SDKs are always from prebuilt
+ return true
+ }
+ // "", "none", "core_platform" fall here
+ return false
+}
+
+// effectiveVersion converts an sdkSpec into the concrete sdkVersion that the module
+// should use. For modules targeting an unreleased SDK (meaning it does not yet have a number)
+// it returns android.FutureApiLevel(10000).
+func (s sdkSpec) effectiveVersion(ctx android.EarlyModuleContext) (sdkVersion, error) {
+ if !s.valid() {
+ return s.version, fmt.Errorf("invalid sdk version %q", s.raw)
+ }
+ if ctx.Config().IsPdkBuild() {
+ s = s.forPdkBuild(ctx)
}
+ if s.version.isNumbered() {
+ return s.version, nil
+ }
+ return sdkVersion(ctx.Config().DefaultAppTargetSdkInt()), nil
+}
- toPrebuilt := func(sdk string) sdkDep {
- var api, v string
- if strings.Contains(sdk, "_") {
- t := strings.Split(sdk, "_")
- api = t[0]
- v = t[1]
+// effectiveVersionString converts an sdkSpec into the concrete version string that the module
+// should use. For modules targeting an unreleased SDK (meaning it does not yet have a number)
+// it returns the codename (P, Q, R, etc.)
+func (s sdkSpec) effectiveVersionString(ctx android.EarlyModuleContext) (string, error) {
+ ver, err := s.effectiveVersion(ctx)
+ if err == nil && int(ver) == ctx.Config().DefaultAppTargetSdkInt() {
+ return ctx.Config().DefaultAppTargetSdk(), nil
+ }
+ return ver.String(), err
+}
+
+func sdkSpecFrom(str string) sdkSpec {
+ switch str {
+ // special cases first
+ case "":
+ return sdkSpec{sdkPrivate, sdkVersionNone, str}
+ case "none":
+ return sdkSpec{sdkNone, sdkVersionNone, str}
+ case "core_platform":
+ return sdkSpec{sdkCorePlatform, sdkVersionNone, str}
+ default:
+ // the syntax is [kind_]version
+ sep := strings.LastIndex(str, "_")
+
+ var kindString string
+ if sep == 0 {
+ return sdkSpec{sdkInvalid, sdkVersionNone, str}
+ } else if sep == -1 {
+ kindString = ""
+ } else {
+ kindString = str[0:sep]
+ }
+ versionString := str[sep+1 : len(str)]
+
+ var kind sdkKind
+ switch kindString {
+ case "":
+ kind = sdkPublic
+ case "core":
+ kind = sdkCore
+ case "system":
+ kind = sdkSystem
+ case "test":
+ kind = sdkTest
+ default:
+ return sdkSpec{sdkInvalid, sdkVersionNone, str}
+ }
+
+ var version sdkVersion
+ if versionString == "current" {
+ version = sdkVersionCurrent
+ } else if i, err := strconv.Atoi(versionString); err == nil {
+ version = sdkVersion(i)
} else {
- api = "public"
- v = sdk
+ return sdkSpec{sdkInvalid, sdkVersionNone, str}
}
- dir := filepath.Join("prebuilts", "sdk", v, api)
+
+ return sdkSpec{kind, version, str}
+ }
+}
+
+func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext sdkContext) sdkDep {
+ sdkVersion := sdkContext.sdkVersion()
+ if !sdkVersion.valid() {
+ ctx.PropertyErrorf("sdk_version", "invalid version %q", sdkVersion.raw)
+ return sdkDep{}
+ }
+
+ if ctx.Config().IsPdkBuild() {
+ sdkVersion = sdkVersion.forPdkBuild(ctx)
+ }
+
+ if sdkVersion.usePrebuilt(ctx) {
+ dir := filepath.Join("prebuilts", "sdk", sdkVersion.version.String(), sdkVersion.kind.String())
jar := filepath.Join(dir, "android.jar")
// There's no aidl for other SDKs yet.
// TODO(77525052): Add aidl files for other SDKs too.
- public_dir := filepath.Join("prebuilts", "sdk", v, "public")
+ public_dir := filepath.Join("prebuilts", "sdk", sdkVersion.version.String(), "public")
aidl := filepath.Join(public_dir, "framework.aidl")
jarPath := android.ExistentPathForSource(ctx, jar)
aidlPath := android.ExistentPathForSource(ctx, aidl)
@@ -122,17 +298,17 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext sdkContext) sdkDep
if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.Config().AllowMissingDependencies() {
return sdkDep{
invalidVersion: true,
- bootclasspath: []string{fmt.Sprintf("sdk_%s_%s_android", api, v)},
+ bootclasspath: []string{fmt.Sprintf("sdk_%s_%s_android", sdkVersion.kind, sdkVersion.version.String())},
}
}
if !jarPath.Valid() {
- ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", sdk, jar)
+ ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", sdkVersion.raw, jar)
return sdkDep{}
}
if !aidlPath.Valid() {
- ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", sdk, aidl)
+ ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", sdkVersion.raw, aidl)
return sdkDep{}
}
@@ -156,31 +332,26 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext sdkContext) sdkDep
// Ensures that the specificed system SDK version is one of BOARD_SYSTEMSDK_VERSIONS (for vendor apks)
// or PRODUCT_SYSTEMSDK_VERSIONS (for other apks or when BOARD_SYSTEMSDK_VERSIONS is not set)
- if strings.HasPrefix(v, "system_") && numericSdkVersion != android.FutureApiLevel {
+ if sdkVersion.kind == sdkSystem && sdkVersion.version.isNumbered() {
allowed_versions := ctx.DeviceConfig().PlatformSystemSdkVersions()
if ctx.DeviceSpecific() || ctx.SocSpecific() {
if len(ctx.DeviceConfig().SystemSdkVersions()) > 0 {
allowed_versions = ctx.DeviceConfig().SystemSdkVersions()
}
}
- if len(allowed_versions) > 0 && !android.InList(strconv.Itoa(numericSdkVersion), allowed_versions) {
+ if len(allowed_versions) > 0 && !android.InList(sdkVersion.version.String(), allowed_versions) {
ctx.PropertyErrorf("sdk_version", "incompatible sdk version %q. System SDK version should be one of %q",
- v, allowed_versions)
+ sdkVersion.raw, allowed_versions)
}
}
- if ctx.Config().UnbundledBuildUsePrebuiltSdks() &&
- v != "" && v != "none" && v != "core_platform" {
- return toPrebuilt(v)
- }
-
- switch v {
- case "":
+ switch sdkVersion.kind {
+ case sdkPrivate:
return sdkDep{
useDefaultLibs: true,
frameworkResModule: "framework-res",
}
- case "none":
+ case sdkNone:
systemModules := sdkContext.systemModules()
if systemModules == "" {
ctx.PropertyErrorf("sdk_version",
@@ -197,22 +368,22 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext sdkContext) sdkDep
systemModules: systemModules,
bootclasspath: []string{systemModules},
}
- case "core_platform":
+ case sdkCorePlatform:
return sdkDep{
useDefaultLibs: true,
frameworkResModule: "framework-res",
noFrameworksLibs: true,
}
- case "current":
+ case sdkPublic:
return toModule("android_stubs_current", "framework-res", sdkFrameworkAidlPath(ctx))
- case "system_current":
+ case sdkSystem:
return toModule("android_system_stubs_current", "framework-res", sdkFrameworkAidlPath(ctx))
- case "test_current":
+ case sdkTest:
return toModule("android_test_stubs_current", "framework-res", sdkFrameworkAidlPath(ctx))
- case "core_current":
+ case sdkCore:
return toModule("core.current.stubs", "", nil)
default:
- return toPrebuilt(v)
+ panic(fmt.Errorf("invalid sdk %q", sdkVersion.raw))
}
}
@@ -245,6 +416,15 @@ func (sdkPreSingleton) GenerateBuildActions(ctx android.SingletonContext) {
ctx.Config().Once(sdkVersionsKey, func() interface{} { return sdkVersions })
}
+func LatestSdkVersionInt(ctx android.EarlyModuleContext) int {
+ sdkVersions := ctx.Config().Get(sdkVersionsKey).([]int)
+ latestSdkVersion := 0
+ if len(sdkVersions) > 0 {
+ latestSdkVersion = sdkVersions[len(sdkVersions)-1]
+ }
+ return latestSdkVersion
+}
+
func sdkSingletonFactory() android.Singleton {
return sdkSingleton{}
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 72c4a7c63..530e02c59 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -650,27 +650,27 @@ func (module *SdkLibrary) createXmlFile(mctx android.LoadHookContext) {
mctx.CreateModule(android.PrebuiltEtcFactory, &etcProps)
}
-func (module *SdkLibrary) PrebuiltJars(ctx android.BaseModuleContext, sdkVersion string) android.Paths {
- var api, v string
- if sdkVersion == "" || sdkVersion == "none" {
- api = "system"
- v = "current"
- } else if strings.Contains(sdkVersion, "_") {
- t := strings.Split(sdkVersion, "_")
- api = t[0]
- v = t[1]
+func (module *SdkLibrary) PrebuiltJars(ctx android.BaseModuleContext, s sdkSpec) android.Paths {
+ var ver sdkVersion
+ var kind sdkKind
+ if s.usePrebuilt(ctx) {
+ ver = s.version
+ kind = s.kind
} else {
- api = "public"
- v = sdkVersion
+ // We don't have prebuilt SDK for the specific sdkVersion.
+ // Instead of breaking the build, fallback to use "system_current"
+ ver = sdkVersionCurrent
+ kind = sdkSystem
}
- dir := filepath.Join("prebuilts", "sdk", v, api)
+
+ dir := filepath.Join("prebuilts", "sdk", ver.String(), kind.String())
jar := filepath.Join(dir, module.BaseModuleName()+".jar")
jarPath := android.ExistentPathForSource(ctx, jar)
if !jarPath.Valid() {
if ctx.Config().AllowMissingDependencies() {
return android.Paths{android.PathForSource(ctx, jar)}
} else {
- ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", sdkVersion, jar)
+ ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", s.raw, jar)
}
return nil
}
@@ -678,32 +678,34 @@ func (module *SdkLibrary) PrebuiltJars(ctx android.BaseModuleContext, sdkVersion
}
// to satisfy SdkLibraryDependency interface
-func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion string) android.Paths {
+func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
// This module is just a wrapper for the stubs.
if ctx.Config().UnbundledBuildUsePrebuiltSdks() {
return module.PrebuiltJars(ctx, sdkVersion)
} else {
- if strings.HasPrefix(sdkVersion, "system_") {
+ switch sdkVersion.kind {
+ case sdkSystem:
return module.systemApiStubsPath
- } else if sdkVersion == "" {
+ case sdkPrivate:
return module.Library.HeaderJars()
- } else {
+ default:
return module.publicApiStubsPath
}
}
}
// to satisfy SdkLibraryDependency interface
-func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion string) android.Paths {
+func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
// This module is just a wrapper for the stubs.
if ctx.Config().UnbundledBuildUsePrebuiltSdks() {
return module.PrebuiltJars(ctx, sdkVersion)
} else {
- if strings.HasPrefix(sdkVersion, "system_") {
+ switch sdkVersion.kind {
+ case sdkSystem:
return module.systemApiStubsImplPath
- } else if sdkVersion == "" {
+ case sdkPrivate:
return module.Library.ImplementationJars()
- } else {
+ default:
return module.publicApiStubsImplPath
}
}
@@ -923,13 +925,13 @@ func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
}
// to satisfy SdkLibraryDependency interface
-func (module *sdkLibraryImport) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion string) android.Paths {
+func (module *sdkLibraryImport) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
// This module is just a wrapper for the prebuilt stubs.
return module.stubsPath
}
// to satisfy SdkLibraryDependency interface
-func (module *sdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion string) android.Paths {
+func (module *sdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
// This module is just a wrapper for the stubs.
return module.stubsPath
}