diff options
author | Sam Mortimer <sam@mortimer.me.uk> | 2019-10-07 11:41:14 -0700 |
---|---|---|
committer | Michael Bestas <mkbestas@lineageos.org> | 2020-12-08 22:28:30 +0200 |
commit | ddf5458d148e20b325182f1ee7d80ab8aed86e2d (patch) | |
tree | fc765e3a43d63eab23435deda5ae6ed956ff36ba | |
parent | 90783142d5e53e22fead18d736a64e54e05bcd82 (diff) |
soong: Give priority to modules in exported namespaces for bootjars
* Looking for modules that provide a boot jar is currently
done by module name match only. This breaks when you
have multiple copies of the same module in your build
tree (eg in another device).
* Add a new mutator that marks the modules that should be used
for bootjar content.
* The logic is simple: give priority to modules that are in
exported soong namespace.
Change-Id: I2476174b892475c14a9f10b5e66b8496186f81c0
-rw-r--r-- | android/Android.bp | 1 | ||||
-rw-r--r-- | android/bootjar.go | 117 | ||||
-rw-r--r-- | android/module.go | 7 | ||||
-rw-r--r-- | apex/apex_test.go | 3 | ||||
-rw-r--r-- | java/dexpreopt_bootjars.go | 4 | ||||
-rw-r--r-- | java/dexpreopt_bootjars_test.go | 2 | ||||
-rw-r--r-- | java/hiddenapi.go | 9 |
7 files changed, 142 insertions, 1 deletions
diff --git a/android/Android.bp b/android/Android.bp index e0664a13c..e0cf40243 100644 --- a/android/Android.bp +++ b/android/Android.bp @@ -15,6 +15,7 @@ bootstrap_go_package { "apex.go", "api_levels.go", "arch.go", + "bootjar.go", "config.go", "csuite_config.go", "defaults.go", diff --git a/android/bootjar.go b/android/bootjar.go new file mode 100644 index 000000000..ea04dc8f4 --- /dev/null +++ b/android/bootjar.go @@ -0,0 +1,117 @@ +// Copyright (C) 2019 The LineageOS Project +// +// 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 android + +import ( + "strings" +) + +// Keys are bootjar name, value is whether or not +// we've marked a module as being a provider for it. +var jarMap map[string]bool + +func init() { + PreArchMutators(RegisterBootJarMutators) +} + +// Note: registration function is structured this way so that it can be included +// from soong module tests. +func RegisterBootJarMutators(ctx RegisterMutatorsContext) { + // Note: can't use Parallel() since we touch global jarMap + ctx.TopDown("bootjar_exportednamespace", bootJarMutatorExportedNamespace) + ctx.TopDown("bootjar_anynamespace", bootJarMutatorAnyNamespace) +} + +func mutatorInit(mctx TopDownMutatorContext) { + // Did we init already ? + if jarMap != nil { + return + } + + jarMap = make(map[string]bool) + for _, moduleName := range mctx.Config().BootJars() { + jarMap[moduleName] = false + } +} + +// Mark modules in soong exported namespace as providing a boot jar. +func bootJarMutatorExportedNamespace(mctx TopDownMutatorContext) { + bootJarMutator(mctx, true) +} + +// Mark modules in any namespace (incl root) as providing a boot jar. +func bootJarMutatorAnyNamespace(mctx TopDownMutatorContext) { + bootJarMutator(mctx, false) +} + +func bootJarMutator(mctx TopDownMutatorContext, requireExportedNamespace bool) { + mutatorInit(mctx) + + module, ok := mctx.Module().(Module) + if !ok { + // Not a proper module + return + } + + // Does this module produce a dex jar ? + if _, ok := module.(interface{ DexJar() Path }); !ok { + // No + return + } + + // If jarMap is empty we must be running in a test so + // set boot jar provide to true for all modules. + if len(jarMap) == 0 { + module.base().commonProperties.BootJarProvider = true + return + } + + name := mctx.ModuleName() + dir := mctx.ModuleDir() + + // Special treatment for hiddenapi modules - create extra + // jarMap entries if needed. + baseName := strings.TrimSuffix(name, "-hiddenapi") + if name != baseName { + _, baseIsBootJar := jarMap[baseName] + _, alreadyExists := jarMap[name] + if baseIsBootJar && !alreadyExists { + // This is a hidden api module whose base name exists in the boot jar list + // and we've not visited it before. Create a map entry for it. + jarMap[name] = false + } + } + + // Does this module match the name of a boot jar ? + if found, exists := jarMap[name]; !exists || found { + // No + return + } + + if requireExportedNamespace { + for _, n := range mctx.Config().ExportedNamespaces() { + if strings.HasPrefix(dir, n) { + jarMap[name] = true + module.base().commonProperties.BootJarProvider = true + break + } + } + } else { + jarMap[name] = true + module.base().commonProperties.BootJarProvider = true + } + + return +} diff --git a/android/module.go b/android/module.go index 285702965..35eb17535 100644 --- a/android/module.go +++ b/android/module.go @@ -530,6 +530,9 @@ type commonProperties struct { // set by ImageMutator ImageVariation string `blueprint:"mutated"` + + // Whether this module provides a boot jar + BootJarProvider bool `blueprint:"mutated"` } type hostAndDeviceProperties struct { @@ -795,6 +798,10 @@ func (m *ModuleBase) String() string { return sb.String() } +func (a *ModuleBase) BootJarProvider() bool { + return a.commonProperties.BootJarProvider +} + // BaseModuleName returns the name of the module as specified in the blueprints file. func (m *ModuleBase) BaseModuleName() string { return String(m.nameProperties.Name) diff --git a/apex/apex_test.go b/apex/apex_test.go index fe2de4754..ebe8cfbf5 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -199,6 +199,7 @@ func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*andr // from android package android.RegisterPackageBuildComponents(ctx) + ctx.PreArchMutators(android.RegisterBootJarMutators) ctx.PreArchMutators(android.RegisterVisibilityRuleChecker) ctx.RegisterModuleType("apex", BundleFactory) @@ -4704,6 +4705,7 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg, bp string, transformDe ctx.RegisterModuleType("apex", BundleFactory) ctx.RegisterModuleType("apex_key", ApexKeyFactory) ctx.RegisterModuleType("filegroup", android.FileGroupFactory) + ctx.PreArchMutators(android.RegisterBootJarMutators) ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) cc.RegisterRequiredBuildComponentsForTest(ctx) java.RegisterJavaBuildComponents(ctx) @@ -4914,6 +4916,7 @@ func testApexPermittedPackagesRules(t *testing.T, errmsg, bp string, apexBootJar ctx := android.NewTestArchContext() ctx.RegisterModuleType("apex", BundleFactory) ctx.RegisterModuleType("apex_key", ApexKeyFactory) + ctx.PreArchMutators(android.RegisterBootJarMutators) ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) cc.RegisterRequiredBuildComponentsForTest(ctx) java.RegisterJavaBuildComponents(ctx) diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index e0609a035..d40d72e09 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -310,6 +310,10 @@ func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootI // This logic is tested in the apex package to avoid import cycle apex <-> java. bootDexJars := make(android.Paths, len(image.modules)) ctx.VisitAllModules(func(module android.Module) { + if m, ok := module.(interface{ BootJarProvider() bool }); !ok || + !m.BootJarProvider() { + return + } if i, j := getBootImageJar(ctx, image, module); i != -1 { bootDexJars[i] = j } diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go index e7b3c3ba9..b685e9b3f 100644 --- a/java/dexpreopt_bootjars_test.go +++ b/java/dexpreopt_bootjars_test.go @@ -53,6 +53,8 @@ func TestDexpreoptBootJars(t *testing.T) { ctx := testContext() + ctx.PreArchMutators(android.RegisterBootJarMutators) + RegisterDexpreoptBootJarsComponents(ctx) run(t, ctx, config) diff --git a/java/hiddenapi.go b/java/hiddenapi.go index b5a021785..36ac0619f 100644 --- a/java/hiddenapi.go +++ b/java/hiddenapi.go @@ -77,7 +77,14 @@ func (h *hiddenAPI) hiddenAPI(ctx android.ModuleContext, name string, primary bo // 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()) { + isBootJarProvider := false + ctx.VisitAllModuleVariants(func(module android.Module) { + if m, ok := module.(interface{ BootJarProvider() bool }); ok && + m.BootJarProvider() { + isBootJarProvider = true + } + }) + if isBootJarProvider && 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") |