Merge changes I8e8e8b01,Ifb1f54d5,I9986e64f
* changes:
Add systemserverclasspath_fragments property to apex.
Add "contents" property to systemserverclasspath_fragment.
Move classpaths.proto related info into a separate provider.
diff --git a/apex/Android.bp b/apex/Android.bp
index e234181..14c8771 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -32,6 +32,7 @@
"apex_test.go",
"bootclasspath_fragment_test.go",
"platform_bootclasspath_test.go",
+ "systemserver_classpath_fragment_test.go",
"vndk_test.go",
],
pluginFor: ["soong_build"],
diff --git a/apex/apex.go b/apex/apex.go
index a8fbf22..7b2e19d 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -102,6 +102,9 @@
// List of bootclasspath fragments that are embedded inside this APEX bundle.
Bootclasspath_fragments []string
+ // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
+ Systemserverclasspath_fragments []string
+
// List of java libraries that are embedded inside this APEX bundle.
Java_libs []string
@@ -575,6 +578,7 @@
executableTag = dependencyTag{name: "executable", payload: true}
fsTag = dependencyTag{name: "filesystem", payload: true}
bcpfTag = dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true}
+ sscpfTag = dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true}
compatConfigTag = dependencyTag{name: "compatConfig", payload: true, sourceOnly: true}
javaLibTag = dependencyTag{name: "javaLib", payload: true}
jniLibTag = dependencyTag{name: "jniLib", payload: true}
@@ -755,6 +759,7 @@
// Common-arch dependencies come next
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.properties.Bootclasspath_fragments...)
+ ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.properties.Systemserverclasspath_fragments...)
ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...)
ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.properties.Bpfs...)
ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
@@ -1715,6 +1720,15 @@
filesInfo = append(filesInfo, filesToAdd...)
return true
}
+ case sscpfTag:
+ {
+ if _, ok := child.(*java.SystemServerClasspathModule); !ok {
+ ctx.PropertyErrorf("systemserverclasspath_fragments", "%q is not a systemserverclasspath_fragment module", depName)
+ return false
+ }
+ filesInfo = append(filesInfo, apexClasspathFragmentProtoFile(ctx, child))
+ return true
+ }
case javaLibTag:
switch child.(type) {
case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
@@ -1941,7 +1955,16 @@
default:
ctx.PropertyErrorf("bootclasspath_fragments", "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
}
-
+ } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
+ // Add the contents of the systemserverclasspath fragment to the apex.
+ switch child.(type) {
+ case *java.Library, *java.SdkLibrary:
+ af := apexFileForJavaModule(ctx, child.(javaModule))
+ filesInfo = append(filesInfo, af)
+ return true // track transitive dependencies
+ default:
+ ctx.PropertyErrorf("systemserverclasspath_fragments", "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
+ }
} else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
// nothing
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
@@ -2106,13 +2129,19 @@
}
// Add classpaths.proto config.
- classpathProtoOutput := bootclasspathFragmentInfo.ClasspathFragmentProtoOutput
- classpathProto := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), bootclasspathFragmentInfo.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
- filesToAdd = append(filesToAdd, classpathProto)
+ filesToAdd = append(filesToAdd, apexClasspathFragmentProtoFile(ctx, module))
return filesToAdd
}
+// apexClasspathFragmentProtoFile returns apexFile structure defining the classpath.proto config that
+// the module contributes to the apex.
+func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) apexFile {
+ fragmentInfo := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
+ classpathProtoOutput := fragmentInfo.ClasspathFragmentProtoOutput
+ return newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), fragmentInfo.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
+}
+
// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
// content module, i.e. a library that is part of the bootclasspath.
func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile {
diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go
new file mode 100644
index 0000000..e1a101a
--- /dev/null
+++ b/apex/systemserver_classpath_fragment_test.go
@@ -0,0 +1,78 @@
+// Copyright (C) 2021 The Android Open Source 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 apex
+
+import (
+ "testing"
+
+ "android/soong/android"
+ "android/soong/java"
+)
+
+var prepareForTestWithSystemserverclasspathFragment = android.GroupFixturePreparers(
+ java.PrepareForTestWithDexpreopt,
+ PrepareForTestWithApexBuildComponents,
+)
+
+func TestSystemserverclasspathFragmentContents(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForTestWithSystemserverclasspathFragment,
+ prepareForTestWithMyapex,
+ ).RunTestWithBp(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ systemserverclasspath_fragments: [
+ "mysystemserverclasspathfragment",
+ ],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_library {
+ name: "foo",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ systemserverclasspath_fragment {
+ name: "mysystemserverclasspathfragment",
+ contents: [
+ "foo",
+ ],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ `)
+
+ ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex_image", []string{
+ "etc/classpaths/mysystemserverclasspathfragment.pb",
+ "javalib/foo.jar",
+ })
+
+ java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex_image", []string{
+ `myapex.key`,
+ `mysystemserverclasspathfragment`,
+ })
+}
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index b6b877b..5d8a8e5 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -268,22 +268,6 @@
// BootclasspathFragmentApexContentInfo contains the bootclasspath_fragments contributions to the
// apex contents.
type BootclasspathFragmentApexContentInfo struct {
- // ClasspathFragmentProtoOutput is an output path for the generated classpaths.proto config of this module.
- //
- // The file should be copied to a relevant place on device, see ClasspathFragmentProtoInstallDir
- // for more details.
- ClasspathFragmentProtoOutput android.OutputPath
-
- // ClasspathFragmentProtoInstallDir contains information about on device location for the generated classpaths.proto file.
- //
- // The path encodes expected sub-location within partitions, i.e. etc/classpaths/<proto-file>,
- // for ClasspathFragmentProtoOutput. To get sub-location, instead of the full output / make path
- // use android.InstallPath#Rel().
- //
- // This is only relevant for APEX modules as they perform their own installation; while regular
- // system files are installed via ClasspathFragmentBase#androidMkEntries().
- ClasspathFragmentProtoInstallDir android.InstallPath
-
// The image config, internal to this module (and the dex_bootjars singleton).
//
// Will be nil if the BootclasspathFragmentApexContentInfo has not been provided for a specific module. That can occur
@@ -396,25 +380,19 @@
// Perform hidden API processing.
b.generateHiddenAPIBuildActions(ctx, contents)
- // Construct the boot image info from the config.
- info := BootclasspathFragmentApexContentInfo{
- ClasspathFragmentProtoInstallDir: b.classpathFragmentBase().installDirPath,
- ClasspathFragmentProtoOutput: b.classpathFragmentBase().outputFilepath,
- imageConfig: nil,
- }
-
if !SkipDexpreoptBootJars(ctx) {
// Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
// GenerateSingletonBuildActions method as it cannot create it for itself.
dexpreopt.GetGlobalSoongConfig(ctx)
- info.imageConfig = b.getImageConfig(ctx)
// Only generate the boot image if the configuration does not skip it.
b.generateBootImageBuildActions(ctx, contents)
- }
- // Make it available for other modules.
- ctx.SetProvider(BootclasspathFragmentApexContentInfoProvider, info)
+ // Make the boot image info available for other modules
+ ctx.SetProvider(BootclasspathFragmentApexContentInfoProvider, BootclasspathFragmentApexContentInfo{
+ imageConfig: b.getImageConfig(ctx),
+ })
+ }
}
// generateClasspathProtoBuildActions generates all required build actions for classpath.proto config
diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go
index 7422fa2..7408090 100644
--- a/java/classpath_fragment.go
+++ b/java/classpath_fragment.go
@@ -18,6 +18,7 @@
import (
"fmt"
+ "github.com/google/blueprint"
"strings"
"android/soong/android"
@@ -120,6 +121,12 @@
FlagWithOutput("--output=", c.outputFilepath)
rule.Build("classpath_fragment", "Compiling "+c.outputFilepath.String())
+
+ classpathProtoInfo := ClasspathFragmentProtoContentInfo{
+ ClasspathFragmentProtoInstallDir: c.installDirPath,
+ ClasspathFragmentProtoOutput: c.outputFilepath,
+ }
+ ctx.SetProvider(ClasspathFragmentProtoContentInfoProvider, classpathProtoInfo)
}
func writeClasspathsJson(ctx android.ModuleContext, output android.WritablePath, jars []classpathJar) {
@@ -157,3 +164,23 @@
},
}}
}
+
+var ClasspathFragmentProtoContentInfoProvider = blueprint.NewProvider(ClasspathFragmentProtoContentInfo{})
+
+type ClasspathFragmentProtoContentInfo struct {
+ // ClasspathFragmentProtoOutput is an output path for the generated classpaths.proto config of this module.
+ //
+ // The file should be copied to a relevant place on device, see ClasspathFragmentProtoInstallDir
+ // for more details.
+ ClasspathFragmentProtoOutput android.OutputPath
+
+ // ClasspathFragmentProtoInstallDir contains information about on device location for the generated classpaths.proto file.
+ //
+ // The path encodes expected sub-location within partitions, i.e. etc/classpaths/<proto-file>,
+ // for ClasspathFragmentProtoOutput. To get sub-location, instead of the full output / make path
+ // use android.InstallPath#Rel().
+ //
+ // This is only relevant for APEX modules as they perform their own installation; while regular
+ // system files are installed via ClasspathFragmentBase#androidMkEntries().
+ ClasspathFragmentProtoInstallDir android.InstallPath
+}
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index cc5ff96..a505c6d 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -17,6 +17,7 @@
import (
"android/soong/android"
"android/soong/dexpreopt"
+ "github.com/google/blueprint"
)
func init() {
@@ -66,24 +67,63 @@
}).(android.ConfiguredJarList)
}
-type systemServerClasspathModule struct {
+type SystemServerClasspathModule struct {
android.ModuleBase
+ android.ApexModuleBase
ClasspathFragmentBase
+
+ properties systemServerClasspathFragmentProperties
+}
+
+func (s *SystemServerClasspathModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
+ return nil
+}
+
+type systemServerClasspathFragmentProperties struct {
+ // The contents of this systemserverclasspath_fragment, could be either java_library, or java_sdk_library.
+ //
+ // The order of this list matters as it is the order that is used in the SYSTEMSERVERCLASSPATH.
+ Contents []string
}
func systemServerClasspathFactory() android.Module {
- m := &systemServerClasspathModule{}
+ m := &SystemServerClasspathModule{}
+ m.AddProperties(&m.properties)
+ android.InitApexModule(m)
initClasspathFragment(m, SYSTEMSERVERCLASSPATH)
android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
return m
}
-func (s *systemServerClasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (s *SystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if len(s.properties.Contents) == 0 {
+ ctx.PropertyErrorf("contents", "empty contents are not allowed")
+ }
+
s.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJarListToClasspathJars(ctx, s.ClasspathFragmentToConfiguredJarList(ctx)))
}
-func (s *systemServerClasspathModule) ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList {
+func (s *SystemServerClasspathModule) ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList {
// TODO(satayev): populate with actual content
return android.EmptyConfiguredJarList()
}
+
+type systemServerClasspathFragmentContentDependencyTag struct {
+ blueprint.BaseDependencyTag
+}
+
+// The tag used for the dependency between the systemserverclasspath_fragment module and its contents.
+var systemServerClasspathFragmentContentDepTag = systemServerClasspathFragmentContentDependencyTag{}
+
+func IsSystemServerClasspathFragmentContentDepTag(tag blueprint.DependencyTag) bool {
+ return tag == systemServerClasspathFragmentContentDepTag
+}
+
+func (s *SystemServerClasspathModule) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
+ module := ctx.Module()
+
+ for _, name := range s.properties.Contents {
+ ctx.AddDependency(module, systemServerClasspathFragmentContentDepTag, name)
+ }
+}
diff --git a/java/systemserver_classpath_fragment_test.go b/java/systemserver_classpath_fragment_test.go
index 6126d5e..5272f27 100644
--- a/java/systemserver_classpath_fragment_test.go
+++ b/java/systemserver_classpath_fragment_test.go
@@ -20,13 +20,13 @@
"android/soong/android"
)
-var prepareForTestWithSystemserverClasspath = android.GroupFixturePreparers(
+var prepareForTestWithSystemServerClasspath = android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
)
-func TestSystemserverClasspathVariant(t *testing.T) {
+func TestPlatformSystemserverClasspathVariant(t *testing.T) {
result := android.GroupFixturePreparers(
- prepareForTestWithSystemserverClasspath,
+ prepareForTestWithSystemServerClasspath,
android.FixtureWithRootAndroidBp(`
platform_systemserverclasspath {
name: "platform-systemserverclasspath",
@@ -38,9 +38,9 @@
android.AssertIntEquals(t, "expect 1 variant", 1, len(variants))
}
-func TestSystemserverClasspath_ClasspathFragmentPaths(t *testing.T) {
+func TestPlatformSystemserverClasspath_ClasspathFragmentPaths(t *testing.T) {
result := android.GroupFixturePreparers(
- prepareForTestWithSystemserverClasspath,
+ prepareForTestWithSystemServerClasspath,
android.FixtureWithRootAndroidBp(`
platform_systemserverclasspath {
name: "platform-systemserverclasspath",
@@ -53,9 +53,9 @@
android.AssertPathRelativeToTopEquals(t, "install filepath", "out/soong/target/product/test_device/system/etc/classpaths", p.ClasspathFragmentBase.installDirPath)
}
-func TestSystemserverClasspathModule_AndroidMkEntries(t *testing.T) {
+func TestPlatformSystemserverClasspathModule_AndroidMkEntries(t *testing.T) {
preparer := android.GroupFixturePreparers(
- prepareForTestWithSystemserverClasspath,
+ prepareForTestWithSystemServerClasspath,
android.FixtureWithRootAndroidBp(`
platform_systemserverclasspath {
name: "platform-systemserverclasspath",
@@ -95,3 +95,14 @@
}
})
}
+
+func TestSystemserverclasspathFragmentWithoutContents(t *testing.T) {
+ prepareForTestWithSystemServerClasspath.
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
+ `\Qempty contents are not allowed\E`)).
+ RunTestWithBp(t, `
+ systemserverclasspath_fragment {
+ name: "systemserverclasspath-fragment",
+ }
+ `)
+}