Merge "Revert $(LOCAL_PATH) handling for `certificate` and `additional_certificates` properties."
diff --git a/Android.bp b/Android.bp
index 10e6a2e..4d73049 100644
--- a/Android.bp
+++ b/Android.bp
@@ -55,7 +55,6 @@
"android/namespace.go",
"android/neverallow.go",
"android/onceper.go",
- "android/override_module.go",
"android/package_ctx.go",
"android/paths.go",
"android/prebuilt.go",
@@ -376,6 +375,7 @@
"soong-android",
"soong-cc",
"soong-java",
+ "soong-python",
],
srcs: [
"apex/apex.go",
diff --git a/android/config.go b/android/config.go
index 33986f7..24be10a 100644
--- a/android/config.go
+++ b/android/config.go
@@ -895,30 +895,16 @@
}
func (c *deviceConfig) OverrideManifestPackageNameFor(name string) (manifestName string, overridden bool) {
- if newManifestName, overridden := c.manifestPackageNameOverrides().Load(name); overridden {
- return newManifestName.(string), true
- }
return findOverrideValue(c.config.productVariables.ManifestPackageNameOverrides, name,
"invalid override rule %q in PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES should be <module_name>:<manifest_name>")
}
func (c *deviceConfig) OverrideCertificateFor(name string) (certificatePath string, overridden bool) {
- if newCert, overridden := c.certificateOverrides().Load(name); overridden {
- return newCert.(string), true
- }
- newCert, overridden := findOverrideValue(c.config.productVariables.CertificateOverrides, name,
+ return findOverrideValue(c.config.productVariables.CertificateOverrides, name,
"invalid override rule %q in PRODUCT_CERTIFICATE_OVERRIDES should be <module_name>:<certificate_module_name>")
- if overridden {
- // PRODUCT_CERTIFICATE_OVERRIDES only supports cert modules.
- newCert = ":" + newCert
- }
- return newCert, overridden
}
func (c *deviceConfig) OverridePackageNameFor(name string) string {
- if newName, overridden := c.moduleNameOverrides().Load(name); overridden {
- return newName.(string)
- }
newName, overridden := findOverrideValue(
c.config.productVariables.PackageNameOverrides,
name,
diff --git a/android/module.go b/android/module.go
index f2f1af1..2fa7d31 100644
--- a/android/module.go
+++ b/android/module.go
@@ -154,6 +154,7 @@
// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
WalkDeps(visit func(Module, Module) bool)
+ WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool)
Variable(pctx PackageContext, name, value string)
Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
@@ -1067,6 +1068,10 @@
})
}
+func (a *androidModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) {
+ a.ModuleContext.WalkDeps(visit)
+}
+
func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
a.ModuleContext.WalkDeps(func(child, parent blueprint.Module) bool {
childAndroidModule := a.validateAndroidModule(child)
diff --git a/android/override_module.go b/android/override_module.go
deleted file mode 100644
index 9fe5f21..0000000
--- a/android/override_module.go
+++ /dev/null
@@ -1,97 +0,0 @@
-package android
-
-import (
- "github.com/google/blueprint/proptools"
- "sync"
-)
-
-func init() {
- RegisterModuleType("override_module", OverrideModuleFactory)
-}
-
-type OverrideModule struct {
- ModuleBase
- properties OverrideModuleProperties
-}
-
-type OverrideModuleProperties struct {
- // base module to override
- Base *string
-
- // file path or module name (in the form ":module") of a certificate to override with
- Certificate *string
-
- // manifest package name to override with
- Manifest_package_name *string
-}
-
-// TODO(jungjw): Work with the mainline team to see if we can deprecate all PRODUCT_*_OVERRIDES vars
-// and hand over overriding values directly to base module code.
-func processOverrides(ctx LoadHookContext, p *OverrideModuleProperties) {
- base := proptools.String(p.Base)
- if base == "" {
- ctx.PropertyErrorf("base", "base module name must be provided")
- }
-
- config := ctx.DeviceConfig()
- if other, loaded := config.moduleNameOverrides().LoadOrStore(base, ctx.ModuleName()); loaded {
- ctx.ModuleErrorf("multiple overriding modules for %q, the other: %q", base, other.(string))
- }
-
- if p.Certificate != nil {
- config.certificateOverrides().Store(base, *p.Certificate)
- }
-
- if p.Manifest_package_name != nil {
- config.manifestPackageNameOverrides().Store(base, *p.Manifest_package_name)
- }
-}
-
-func (i *OverrideModule) DepsMutator(ctx BottomUpMutatorContext) {
- base := *i.properties.Base
- // Right now, we add a dependency only to check the base module exists, and so are not using a tag here.
- // TODO(jungjw): Add a tag and check the base module type once we finalize supported base module types.
- ctx.AddDependency(ctx.Module(), nil, base)
-}
-
-func (i *OverrideModule) GenerateAndroidBuildActions(ctx ModuleContext) {
- // All the overrides happen in the base module.
- // TODO(jungjw): Check the base module type.
-}
-
-// override_module overrides an existing module with the specified properties.
-//
-// Currently, only android_app is officially supported.
-func OverrideModuleFactory() Module {
- m := &OverrideModule{}
- AddLoadHook(m, func(ctx LoadHookContext) {
- processOverrides(ctx, &m.properties)
- })
- m.AddProperties(&m.properties)
- InitAndroidModule(m)
- return m
-}
-
-var moduleNameOverridesKey = NewOnceKey("moduleNameOverrides")
-
-func (c *deviceConfig) moduleNameOverrides() *sync.Map {
- return c.Once(moduleNameOverridesKey, func() interface{} {
- return &sync.Map{}
- }).(*sync.Map)
-}
-
-var certificateOverridesKey = NewOnceKey("certificateOverrides")
-
-func (c *deviceConfig) certificateOverrides() *sync.Map {
- return c.Once(certificateOverridesKey, func() interface{} {
- return &sync.Map{}
- }).(*sync.Map)
-}
-
-var manifestPackageNameOverridesKey = NewOnceKey("manifestPackageNameOverrides")
-
-func (c *deviceConfig) manifestPackageNameOverrides() *sync.Map {
- return c.Once(manifestPackageNameOverridesKey, func() interface{} {
- return &sync.Map{}
- }).(*sync.Map)
-}
diff --git a/apex/apex.go b/apex/apex.go
index 5d0c52a..f72eef3 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -25,8 +25,10 @@
"android/soong/android"
"android/soong/cc"
"android/soong/java"
+ "android/soong/python"
"github.com/google/blueprint"
+ "github.com/google/blueprint/bootstrap"
"github.com/google/blueprint/proptools"
)
@@ -289,6 +291,8 @@
nativeSharedLib
nativeExecutable
shBinary
+ pyBinary
+ goBinary
javaSharedLib
)
@@ -348,7 +352,7 @@
return "ETC"
case nativeSharedLib:
return "SHARED_LIBRARIES"
- case nativeExecutable, shBinary:
+ case nativeExecutable, shBinary, pyBinary, goBinary:
return "EXECUTABLES"
case javaSharedLib:
return "JAVA_LIBRARIES"
@@ -534,7 +538,7 @@
func (a *apexBundle) getCertString(ctx android.BaseContext) string {
certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
if overridden {
- return certificate
+ return ":" + certificate
}
return String(a.properties.Certificate)
}
@@ -624,6 +628,22 @@
return
}
+func getCopyManifestForPyBinary(py *python.Module) (fileToCopy android.Path, dirInApex string) {
+ dirInApex = "bin"
+ fileToCopy = py.HostToolPath().Path()
+ return
+}
+func getCopyManifestForGoBinary(ctx android.ModuleContext, gb bootstrap.GoBinaryTool) (fileToCopy android.Path, dirInApex string) {
+ dirInApex = "bin"
+ s, err := filepath.Rel(android.PathForOutput(ctx).String(), gb.InstallPath())
+ if err != nil {
+ ctx.ModuleErrorf("Unable to use compiled binary at %s", gb.InstallPath())
+ return
+ }
+ fileToCopy = android.PathForOutput(ctx, s)
+ return
+}
+
func getCopyManifestForShBinary(sh *android.ShBinary) (fileToCopy android.Path, dirInApex string) {
dirInApex = filepath.Join("bin", sh.SubDir())
fileToCopy = sh.OutputFile()
@@ -658,7 +678,7 @@
handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
- ctx.WalkDeps(func(child, parent android.Module) bool {
+ ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
if _, ok := parent.(*apexBundle); ok {
// direct dependencies
depTag := ctx.OtherModuleDependencyTag(child)
@@ -685,8 +705,17 @@
} else if sh, ok := child.(*android.ShBinary); ok {
fileToCopy, dirInApex := getCopyManifestForShBinary(sh)
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, shBinary, sh, nil})
+ } else if py, ok := child.(*python.Module); ok && py.HostToolPath().Valid() {
+ fileToCopy, dirInApex := getCopyManifestForPyBinary(py)
+ filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, pyBinary, py, nil})
+ } else if gb, ok := child.(bootstrap.GoBinaryTool); ok && a.Host() {
+ fileToCopy, dirInApex := getCopyManifestForGoBinary(ctx, gb)
+ // NB: Since go binaries are static we don't need the module for anything here, which is
+ // good since the go tool is a blueprint.Module not an android.Module like we would
+ // normally use.
+ filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, goBinary, nil, nil})
} else {
- ctx.PropertyErrorf("binaries", "%q is neithher cc_binary nor sh_binary", depName)
+ ctx.PropertyErrorf("binaries", "%q is neither cc_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName)
}
case javaLibTag:
if java, ok := child.(*java.Library); ok {
diff --git a/java/app.go b/java/app.go
index 08b2d91..2ff6c98 100644
--- a/java/app.go
+++ b/java/app.go
@@ -93,6 +93,8 @@
// the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
installApkName string
+
+ additionalAaptFlags []string
}
func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
@@ -222,6 +224,8 @@
aaptLinkFlags = append(aaptLinkFlags, "--rename-manifest-package "+manifestPackageName)
}
+ aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
+
a.aapt.buildActions(ctx, sdkContext(a), aaptLinkFlags...)
// apps manifests are handled by aapt, don't let Module see them
@@ -392,7 +396,7 @@
func (a *AndroidApp) getCertString(ctx android.BaseContext) string {
certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
if overridden {
- return certificate
+ return ":" + certificate
}
return String(a.appProperties.Certificate)
}
@@ -441,6 +445,13 @@
}
func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ // Check if the instrumentation target package is overridden before generating build actions.
+ if a.appTestProperties.Instrumentation_for != nil {
+ manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
+ if overridden {
+ a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
+ }
+ }
a.generateAndroidBuildActions(ctx)
a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites)
diff --git a/java/app_test.go b/java/app_test.go
index 313844f..1784fc3 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -748,56 +748,29 @@
}
}
-func TestOverrideModule(t *testing.T) {
- ctx := testJava(t, `
+func TestInstrumentationTargetOverridden(t *testing.T) {
+ bp := `
android_app {
name: "foo",
srcs: ["a.java"],
}
- override_module {
+ android_test {
name: "bar",
- base: "foo",
- certificate: ":new_certificate",
- manifest_package_name: "org.dandroid.bp",
+ instrumentation_for: "foo",
}
+ `
+ config := testConfig(nil)
+ config.TestProductVariables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"}
+ ctx := testAppContext(config, bp, nil)
- android_app_certificate {
- name: "new_certificate",
- certificate: "cert/new_cert",
- }
- `)
+ run(t, ctx, config)
- // The base module still contains all the final outputs after overrides.
- foo := ctx.ModuleForTests("foo", "android_common")
-
- // Check the final apk name
- outputs := foo.AllOutputs()
- e := buildDir + "/target/product/test_device/system/app/bar/bar.apk"
- found := false
- for _, o := range outputs {
- if o == e {
- found = true
- break
- }
- }
- if !found {
- t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
- }
-
- // Check the certificate paths
- signapk := foo.Output("foo.apk")
- signFlags := signapk.Args["certificates"]
- e = "cert/new_cert.x509.pem cert/new_cert.pk8"
- if e != signFlags {
- t.Errorf("Incorrect signing flags, expected: %q, got: %q", e, signFlags)
- }
-
- // Check the manifest package name
- res := foo.Output("package-res.apk")
+ bar := ctx.ModuleForTests("bar", "android_common")
+ res := bar.Output("package-res.apk")
aapt2Flags := res.Args["flags"]
- e = "--rename-manifest-package org.dandroid.bp"
+ e := "--rename-instrumentation-target-package org.dandroid.bp"
if !strings.Contains(aapt2Flags, e) {
- t.Errorf("package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
+ t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
}
}
diff --git a/java/config/config.go b/java/config/config.go
index 75be9e2..e607b1d 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -33,12 +33,6 @@
DefaultLambdaStubsLibrary = "core-lambda-stubs"
SdkLambdaStubsPath = "prebuilts/sdk/tools/core-lambda-stubs.jar"
- // A list of the jars that provide information about usages of the hidden API.
- HiddenAPIExtraAppUsageJars = []string{
- // The core-oj-hiddenapi provides information for the core-oj jar.
- "core-oj-hiddenapi",
- }
-
DefaultJacocoExcludeFilter = []string{"org.junit.*", "org.jacoco.*", "org.mockito.*"}
InstrumentFrameworkModules = []string{
@@ -67,6 +61,7 @@
pctx.StaticVariable("JavacHeapSize", "2048M")
pctx.StaticVariable("JavacHeapFlags", "-J-Xmx${JavacHeapSize}")
+ pctx.StaticVariable("DexFlags", "-JXX:+TieredCompilation -JXX:TieredStopAtLevel=1")
pctx.StaticVariable("CommonJdkFlags", strings.Join([]string{
`-Xmaxerrs 9999999`,
diff --git a/java/config/makevars.go b/java/config/makevars.go
index 156ee26..30552da 100644
--- a/java/config/makevars.go
+++ b/java/config/makevars.go
@@ -81,4 +81,6 @@
ctx.Strict("CLASS2GREYLIST", "${Class2Greylist}")
ctx.Strict("HIDDENAPI", "${HiddenAPI}")
+
+ ctx.Strict("DEX_FLAGS", "${DexFlags}")
}
diff --git a/java/dex.go b/java/dex.go
index 54b7bfc..987129e 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -25,7 +25,7 @@
var d8 = pctx.AndroidStaticRule("d8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
- `${config.D8Cmd} --output $outDir $d8Flags $in && ` +
+ `${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{
@@ -40,7 +40,7 @@
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
`rm -f "$outDict" && ` +
- `${config.R8Cmd} -injars $in --output $outDir ` +
+ `${config.R8Cmd} ${config.DexFlags} -injars $in --output $outDir ` +
`--force-proguard-compatibility ` +
`--no-data-resources ` +
`-printmapping $outDict ` +
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index a35e011..ca68832 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -16,6 +16,7 @@
import (
"path/filepath"
+ "sort"
"strings"
"android/soong/android"
@@ -137,6 +138,8 @@
if global.GenerateApexImage {
d.otherImages = append(d.otherImages, buildBootImage(ctx, apexBootImageConfig(ctx)))
}
+
+ dumpOatRules(ctx, d.defaultBootImage)
}
// buildBootImage takes a bootImageConfig, creates rules to build it, and returns a *bootImage.
@@ -389,6 +392,50 @@
var bootImageProfileRuleKey = android.NewOnceKey("bootImageProfileRule")
+func dumpOatRules(ctx android.SingletonContext, image *bootImage) {
+ var archs []android.ArchType
+ for arch := range image.images {
+ archs = append(archs, arch)
+ }
+ sort.Slice(archs, func(i, j int) bool { return archs[i].String() < archs[j].String() })
+
+ var allPhonies android.Paths
+ for _, arch := range archs {
+ // Create a rule to call oatdump.
+ output := android.PathForOutput(ctx, "boot."+arch.String()+".oatdump.txt")
+ rule := android.NewRuleBuilder()
+ rule.Command().
+ // TODO: for now, use the debug version for better error reporting
+ Tool(ctx.Config().HostToolPath(ctx, "oatdumpd")).
+ FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPaths.Paths(), ":").
+ FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocations, ":").
+ FlagWithArg("--image=", dexpreopt.PathToLocation(image.images[arch], arch)).Implicit(image.images[arch]).
+ FlagWithOutput("--output=", output).
+ FlagWithArg("--instruction-set=", arch.String())
+ rule.Build(pctx, ctx, "dump-oat-boot-"+arch.String(), "dump oat boot "+arch.String())
+
+ // Create a phony rule that depends on the output file and prints the path.
+ phony := android.PathForPhony(ctx, "dump-oat-boot-"+arch.String())
+ rule = android.NewRuleBuilder()
+ rule.Command().
+ Implicit(output).
+ ImplicitOutput(phony).
+ Text("echo").FlagWithArg("Output in ", output.String())
+ rule.Build(pctx, ctx, "phony-dump-oat-boot-"+arch.String(), "dump oat boot "+arch.String())
+
+ allPhonies = append(allPhonies, phony)
+ }
+
+ phony := android.PathForPhony(ctx, "dump-oat-boot")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Phony,
+ Output: phony,
+ Inputs: allPhonies,
+ Description: "dump-oat-boot",
+ })
+
+}
+
// Export paths for default boot image to Make
func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
image := d.defaultBootImage
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index 51ed3dd..6020aba 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -15,10 +15,11 @@
package java
import (
+ "strings"
+
"github.com/google/blueprint"
"android/soong/android"
- "android/soong/java/config"
)
var hiddenAPIGenerateCSVRule = pctx.AndroidStaticRule("hiddenAPIGenerateCSV", blueprint.RuleParams{
@@ -56,20 +57,39 @@
uncompressDex bool) android.ModuleOutPath {
if !ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
- isBootJar := inList(ctx.ModuleName(), ctx.Config().BootJars())
- if isBootJar || inList(ctx.ModuleName(), config.HiddenAPIExtraAppUsageJars) {
+ name := ctx.ModuleName()
+
+ // Modules whose names are of the format <x>-hiddenapi provide hiddenapi information
+ // for the boot jar module <x>. Otherwise, the module provides information for itself.
+ // Either way extract the name of the boot jar module.
+ bootJarName := strings.TrimSuffix(name, "-hiddenapi")
+
+ // If this module is on the boot jars list (or providing information for a module
+ // on the list) then extract the hiddenapi information from it, and if necessary
+ // encode that information in the generated dex file.
+ //
+ // It is important that hiddenapi information is only gathered for/from modules on
+ // that are actually on the boot jars list because the runtime only enforces access
+ // to the hidden API for the bootclassloader. If information is gathered for modules
+ // not on the list then that will cause failures in the CtsHiddenApiBlacklist...
+ // tests.
+ if inList(bootJarName, ctx.Config().BootJars()) {
// Derive the greylist from classes jar.
flagsCSV := android.PathForModuleOut(ctx, "hiddenapi", "flags.csv")
metadataCSV := android.PathForModuleOut(ctx, "hiddenapi", "metadata.csv")
hiddenAPIGenerateCSV(ctx, flagsCSV, metadataCSV, implementationJar)
h.flagsCSVPath = flagsCSV
h.metadataCSVPath = metadataCSV
- }
- if isBootJar {
- hiddenAPIJar := android.PathForModuleOut(ctx, "hiddenapi", ctx.ModuleName()+".jar")
- h.bootDexJarPath = dexJar
- hiddenAPIEncodeDex(ctx, hiddenAPIJar, dexJar, uncompressDex)
- dexJar = hiddenAPIJar
+
+ // If this module is actually on the boot jars list and not providing
+ // hiddenapi information for a module on the boot jars list then encode
+ // the gathered information in the generated dex file.
+ if name == bootJarName {
+ hiddenAPIJar := android.PathForModuleOut(ctx, "hiddenapi", name+".jar")
+ h.bootDexJarPath = dexJar
+ hiddenAPIEncodeDex(ctx, hiddenAPIJar, dexJar, uncompressDex)
+ dexJar = hiddenAPIJar
+ }
}
}
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 23f6cb0..ceafb59 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -89,7 +89,13 @@
// Public API stubs
publicStubModules := []string{
"android_stubs_current",
- "android.test.base.stubs",
+ }
+
+ // Add the android.test.base to the set of stubs only if the android.test.base module is on
+ // the boot jars list as the runtime will only enforce hiddenapi access against modules on
+ // that list.
+ if inList("android.test.base", ctx.Config().BootJars()) {
+ publicStubModules = append(publicStubModules, "android.test.base.stubs")
}
// System API stubs
diff --git a/java/java_test.go b/java/java_test.go
index bbcc9ed..8d3efcb 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -81,13 +81,11 @@
ctx.RegisterModuleType("droiddoc_host", android.ModuleFactoryAdaptor(DroiddocHostFactory))
ctx.RegisterModuleType("droiddoc_template", android.ModuleFactoryAdaptor(ExportedDroiddocDirFactory))
ctx.RegisterModuleType("java_sdk_library", android.ModuleFactoryAdaptor(SdkLibraryFactory))
- ctx.RegisterModuleType("override_module", android.ModuleFactoryAdaptor(android.OverrideModuleFactory))
ctx.RegisterModuleType("prebuilt_apis", android.ModuleFactoryAdaptor(PrebuiltApisFactory))
ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("load_hooks", android.LoadHookMutator).Parallel()
ctx.TopDown("prebuilt_apis", PrebuiltApisMutator).Parallel()
ctx.TopDown("java_sdk_library", SdkLibraryMutator).Parallel()
})
diff --git a/java/sdk_library.go b/java/sdk_library.go
index f2df49b..df4e08b 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -607,6 +607,10 @@
dir := filepath.Join("prebuilts", "sdk", v, api)
jar := filepath.Join(dir, module.BaseModuleName()+".jar")
jarPath := android.ExistentPathForSource(ctx, jar)
+ if !jarPath.Valid() {
+ ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", v, jar)
+ return nil
+ }
return android.Paths{jarPath.Path()}
}