Merge "Support missing a shared library variant."
diff --git a/android/config.go b/android/config.go
index da4f8e2..d0ac4c3 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1028,8 +1028,12 @@
return c.config.productVariables.DeviceKernelHeaders
}
+func (c *config) NativeLineCoverage() bool {
+ return Bool(c.productVariables.NativeLineCoverage)
+}
+
func (c *deviceConfig) NativeCoverageEnabled() bool {
- return Bool(c.config.productVariables.Native_coverage)
+ return Bool(c.config.productVariables.Native_coverage) || Bool(c.config.productVariables.NativeLineCoverage)
}
func (c *deviceConfig) ClangCoverageEnabled() bool {
diff --git a/android/soong_config_modules.go b/android/soong_config_modules.go
index 3e55958..f54e774 100644
--- a/android/soong_config_modules.go
+++ b/android/soong_config_modules.go
@@ -54,7 +54,7 @@
// For example, an Android.bp file could have:
//
// soong_config_module_type_import {
-// from: "device/acme/Android.bp.bp",
+// from: "device/acme/Android.bp",
// module_types: ["acme_cc_defaults"],
// }
//
@@ -139,9 +139,9 @@
}
// soong_config_module_type defines module types with conditionals on Soong config
-// variables from another Android.bp file. The new module type will exist for all
-// modules after the definition in an Android.bp file, and can be imported into other
-// Android.bp files using soong_config_module_type_import.
+// variables. The new module type will exist for all modules after the definition
+// in an Android.bp file, and can be imported into other Android.bp files using
+// soong_config_module_type_import.
//
// For example, an Android.bp file could have:
//
@@ -186,8 +186,6 @@
// srcs: ["*.cpp"],
// }
//
-// And device/acme/Android.bp could have:
-//
// If an acme BoardConfig.mk file contained:
//
// SOONG_CONFIG_NAMESPACES += acme
diff --git a/android/util.go b/android/util.go
index 81f481d..e985fc1 100644
--- a/android/util.go
+++ b/android/util.go
@@ -121,8 +121,19 @@
return IndexList(s, list) != -1
}
-func PrefixInList(s string, list []string) bool {
- for _, prefix := range list {
+// Returns true if the given string s is prefixed with any string in the given prefix list.
+func PrefixInList(s string, prefixList []string) bool {
+ for _, prefix := range prefixList {
+ if strings.HasPrefix(s, prefix) {
+ return true
+ }
+ }
+ return false
+}
+
+// Returns true if any string in the given list has the given prefix.
+func PrefixedStringInList(list []string, prefix string) bool {
+ for _, s := range list {
if strings.HasPrefix(s, prefix) {
return true
}
diff --git a/android/variable.go b/android/variable.go
index c277acc..9625a87 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -252,6 +252,7 @@
ClangTidy *bool `json:",omitempty"`
TidyChecks *string `json:",omitempty"`
+ NativeLineCoverage *bool `json:",omitempty"`
Native_coverage *bool `json:",omitempty"`
ClangCoverage *bool `json:",omitempty"`
CoveragePaths []string `json:",omitempty"`
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 8929910..714045f 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -42,7 +42,11 @@
}}
}
-func (a *apexBundle) androidMkForFiles(w io.Writer, apexName, moduleDir string) []string {
+func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, apexName, moduleDir string) []string {
+ // apexBundleName comes from the 'name' property; apexName comes from 'apex_name' property.
+ // An apex is installed to /system/apex/<apexBundleName> and is activated at /apex/<apexName>
+ // In many cases, the two names are the same, but could be different in general.
+
moduleNames := []string{}
apexType := a.properties.ApexType
// To avoid creating duplicate build rules, run this function only when primaryApexType is true
@@ -52,12 +56,21 @@
return moduleNames
}
+ // b/140136207. When there are overriding APEXes for a VNDK APEX, the symbols file for the overridden
+ // APEX and the overriding APEX will have the same installation paths at /apex/com.android.vndk.v<ver>
+ // as their apexName will be the same. To avoid the path conflicts, skip installing the symbol files
+ // for the overriding VNDK APEXes.
+ symbolFilesNotNeeded := a.vndkApex && len(a.overridableProperties.Overrides) > 0
+ if symbolFilesNotNeeded && apexType != flattenedApex {
+ return moduleNames
+ }
+
var postInstallCommands []string
for _, fi := range a.filesInfo {
if a.linkToSystemLib && fi.transitiveDep && fi.AvailableToPlatform() {
// TODO(jiyong): pathOnDevice should come from fi.module, not being calculated here
linkTarget := filepath.Join("/system", fi.Path())
- linkPath := filepath.Join(a.installDir.ToMakePath().String(), apexName, fi.Path())
+ linkPath := filepath.Join(a.installDir.ToMakePath().String(), apexBundleName, fi.Path())
mkdirCmd := "mkdir -p " + filepath.Dir(linkPath)
linkCmd := "ln -sfn " + linkTarget + " " + linkPath
postInstallCommands = append(postInstallCommands, mkdirCmd, linkCmd)
@@ -75,7 +88,7 @@
if linkToSystemLib {
moduleName = fi.moduleName
} else {
- moduleName = fi.moduleName + "." + apexName + a.suffix
+ moduleName = fi.moduleName + "." + apexBundleName + a.suffix
}
if !android.InList(moduleName, moduleNames) {
@@ -99,8 +112,8 @@
if apexType == flattenedApex {
// /system/apex/<name>/{lib|framework|...}
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join(a.installDir.ToMakePath().String(),
- apexName, fi.installDir))
- if a.primaryApexType {
+ apexBundleName, fi.installDir))
+ if a.primaryApexType && !symbolFilesNotNeeded {
fmt.Fprintln(w, "LOCAL_SOONG_SYMBOL_PATH :=", pathWhenActivated)
}
if len(fi.symlinks) > 0 {
@@ -236,7 +249,7 @@
apexType := a.properties.ApexType
if a.installable() {
apexName := proptools.StringDefault(a.properties.Apex_name, name)
- moduleNames = a.androidMkForFiles(w, apexName, moduleDir)
+ moduleNames = a.androidMkForFiles(w, name, apexName, moduleDir)
}
if apexType == flattenedApex {
diff --git a/apex/apex.go b/apex/apex.go
index 48cdedf..53bdc12 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1194,6 +1194,12 @@
return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
}
+func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
+ dirInApex := filepath.Join("etc", config.SubDir())
+ fileToCopy := config.CompatConfig()
+ return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config)
+}
+
func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp interface {
android.Module
Privileged() bool
@@ -1361,8 +1367,10 @@
case prebuiltTag:
if prebuilt, ok := child.(android.PrebuiltEtcModule); ok {
filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
+ } else if prebuilt, ok := child.(java.PlatformCompatConfigIntf); ok {
+ filesInfo = append(filesInfo, apexFileForCompatConfig(ctx, prebuilt, depName))
} else {
- ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
+ ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc and not a platform_compat_config module", depName)
}
case testTag:
if ccTest, ok := child.(*cc.Module); ok {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index c7ecbc9..faf7ae5 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -299,6 +299,7 @@
ctx.RegisterModuleType("vndk_prebuilt_shared", cc.VndkPrebuiltSharedFactory)
ctx.RegisterModuleType("vndk_libraries_txt", cc.VndkLibrariesTxtFactory)
ctx.RegisterModuleType("prebuilt_etc", android.PrebuiltEtcFactory)
+ ctx.RegisterModuleType("platform_compat_config", java.PlatformCompatConfigFactory)
ctx.RegisterModuleType("sh_binary", android.ShBinaryFactory)
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
java.RegisterJavaBuildComponents(ctx)
@@ -2209,11 +2210,12 @@
}
func TestApexName(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx, config := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
apex_name: "com.android.myapex",
+ native_shared_libs: ["mylib"],
}
apex_key {
@@ -2221,6 +2223,17 @@
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
`)
module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
@@ -2228,6 +2241,16 @@
ensureContains(t, apexManifestRule.Args["opt"], "-v name com.android.myapex")
apexRule := module.Rule("apexRule")
ensureContains(t, apexRule.Args["opt_flags"], "--do_not_check_keyname")
+
+ apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
+ data := android.AndroidMkDataForTest(t, config, "", apexBundle)
+ name := apexBundle.BaseModuleName()
+ prefix := "TARGET_"
+ var builder strings.Builder
+ data.Custom(&builder, name, prefix, "", data)
+ androidMk := builder.String()
+ ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n")
+ ensureNotContains(t, androidMk, "LOCAL_MODULE := mylib.com.android.myapex\n")
}
func TestNonTestApex(t *testing.T) {
@@ -3451,6 +3474,41 @@
ensureContains(t, xml.Args["content"], `<library name="foo" file="/apex/myapex/javalib/foo.jar"`)
}
+func TestCompatConfig(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ prebuilts: ["myjar-platform-compat-config"],
+ java_libs: ["myjar"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ platform_compat_config {
+ name: "myjar-platform-compat-config",
+ src: ":myjar",
+ }
+
+ java_library {
+ name: "myjar",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ compile_dex: true,
+ apex_available: [ "myapex" ],
+ }
+ `)
+ ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
+ "etc/compatconfig/myjar-platform-compat-config.xml",
+ "javalib/myjar.jar",
+ })
+}
+
func TestRejectNonInstallableJavaLibrary(t *testing.T) {
testApexError(t, `"myjar" is not configured to be compiled into dex`, `
apex {
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index fd5a4da..165901d 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -241,39 +241,43 @@
func (info *nativeLibInfo) generatePrebuiltLibrary(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
- // a function for emitting include dirs
- addExportedDirsForNativeLibs := func(lib nativeLibInfoProperties, properties android.BpPropertySet, systemInclude bool) {
- includeDirs := nativeIncludeDirPathsFor(lib, systemInclude)
- if len(includeDirs) == 0 {
- return
- }
- var propertyName string
- if !systemInclude {
- propertyName = "export_include_dirs"
- } else {
- propertyName = "export_system_include_dirs"
- }
- properties.AddProperty(propertyName, includeDirs)
- }
-
pbm := builder.AddPrebuiltModule(member, info.memberType.prebuiltModuleType)
- addExportedDirsForNativeLibs(info.commonProperties, pbm, false /*systemInclude*/)
- addExportedDirsForNativeLibs(info.commonProperties, pbm, true /*systemInclude*/)
+ addPossiblyArchSpecificProperties(info.commonProperties, pbm)
archProperties := pbm.AddPropertySet("arch")
for _, av := range info.archVariantProperties {
archTypeProperties := archProperties.AddPropertySet(av.archType)
+ // Add any arch specific properties inside the appropriate arch: {<arch>: {...}} block
archTypeProperties.AddProperty("srcs", []string{nativeLibraryPathFor(av)})
- // export_* properties are added inside the arch: {<arch>: {...}} block
- addExportedDirsForNativeLibs(av, archTypeProperties, false /*systemInclude*/)
- addExportedDirsForNativeLibs(av, archTypeProperties, true /*systemInclude*/)
+ addPossiblyArchSpecificProperties(av, archTypeProperties)
}
pbm.AddProperty("stl", "none")
pbm.AddProperty("system_shared_libs", []string{})
}
+// Add properties that may, or may not, be arch specific.
+func addPossiblyArchSpecificProperties(libInfo nativeLibInfoProperties, outputProperties android.BpPropertySet) {
+ addExportedDirsForNativeLibs(libInfo, outputProperties, false /*systemInclude*/)
+ addExportedDirsForNativeLibs(libInfo, outputProperties, true /*systemInclude*/)
+}
+
+// a function for emitting include dirs
+func addExportedDirsForNativeLibs(lib nativeLibInfoProperties, properties android.BpPropertySet, systemInclude bool) {
+ includeDirs := nativeIncludeDirPathsFor(lib, systemInclude)
+ if len(includeDirs) == 0 {
+ return
+ }
+ var propertyName string
+ if !systemInclude {
+ propertyName = "export_include_dirs"
+ } else {
+ propertyName = "export_system_include_dirs"
+ }
+ properties.AddProperty(propertyName, includeDirs)
+}
+
const (
nativeIncludeDir = "include"
nativeGeneratedIncludeDir = "include_gen"
diff --git a/java/aapt2.go b/java/aapt2.go
index cfe0dea..04e4de5 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -147,10 +147,16 @@
RspfileContent: "$in",
})
+var mergeAssetsRule = pctx.AndroidStaticRule("mergeAssets",
+ blueprint.RuleParams{
+ Command: `${config.MergeZipsCmd} ${out} ${in}`,
+ CommandDeps: []string{"${config.MergeZipsCmd}"},
+ })
+
func aapt2Link(ctx android.ModuleContext,
packageRes, genJar, proguardOptions, rTxt, extraPackages android.WritablePath,
flags []string, deps android.Paths,
- compiledRes, compiledOverlay android.Paths, splitPackages android.WritablePaths) {
+ compiledRes, compiledOverlay, assetPackages android.Paths, splitPackages android.WritablePaths) {
genDir := android.PathForModuleGen(ctx, "aapt2", "R")
@@ -186,12 +192,25 @@
}
implicitOutputs := append(splitPackages, proguardOptions, genJar, rTxt, extraPackages)
+ linkOutput := packageRes
+
+ // AAPT2 ignores assets in overlays. Merge them after linking.
+ if len(assetPackages) > 0 {
+ linkOutput = android.PathForModuleOut(ctx, "aapt2", "package-res.apk")
+ inputZips := append(android.Paths{linkOutput}, assetPackages...)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: mergeAssetsRule,
+ Inputs: inputZips,
+ Output: packageRes,
+ Description: "merge assets from dependencies",
+ })
+ }
ctx.Build(pctx, android.BuildParams{
Rule: aapt2LinkRule,
Description: "aapt2 link",
Implicits: deps,
- Output: packageRes,
+ Output: linkOutput,
ImplicitOutputs: implicitOutputs,
Args: map[string]string{
"flags": strings.Join(flags, " "),
diff --git a/java/aar.go b/java/aar.go
index d707e36..24c5e7d 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -32,6 +32,7 @@
ExportedRRODirs() []rroDir
ExportedStaticPackages() android.Paths
ExportedManifests() android.Paths
+ ExportedAssets() android.OptionalPath
}
func init() {
@@ -93,6 +94,7 @@
extraAaptPackagesFile android.Path
mergedManifestFile android.Path
noticeFile android.OptionalPath
+ assetPackage android.OptionalPath
isLibrary bool
useEmbeddedNativeLibs bool
useEmbeddedDex bool
@@ -124,6 +126,10 @@
return a.transitiveManifestPaths
}
+func (a *aapt) ExportedAssets() android.OptionalPath {
+ return a.assetPackage
+}
+
func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext,
manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths,
resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) {
@@ -219,9 +225,15 @@
}
}
+var extractAssetsRule = pctx.AndroidStaticRule("extractAssets",
+ blueprint.RuleParams{
+ Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} "assets/**/*"`,
+ CommandDeps: []string{"${config.Zip2ZipCmd}"},
+ })
+
func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, extraLinkFlags ...string) {
- transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, libDeps, libFlags, sdkLibraries :=
+ transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags, sdkLibraries :=
aaptLibs(ctx, sdkContext)
// App manifest file
@@ -321,7 +333,20 @@
}
aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages,
- linkFlags, linkDeps, compiledRes, compiledOverlay, splitPackages)
+ linkFlags, linkDeps, compiledRes, compiledOverlay, assetPackages, splitPackages)
+
+ // Extract assets from the resource package output so that they can be used later in aapt2link
+ // for modules that depend on this one.
+ if android.PrefixedStringInList(linkFlags, "-A ") || len(assetPackages) > 0 {
+ assets := android.PathForModuleOut(ctx, "assets.zip")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: extractAssetsRule,
+ Input: packageRes,
+ Output: assets,
+ Description: "extract assets from built resource file",
+ })
+ a.assetPackage = android.OptionalPathForPath(assets)
+ }
a.aaptSrcJar = srcJar
a.exportPackage = packageRes
@@ -335,7 +360,7 @@
// aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStaticLibs, transitiveStaticLibManifests android.Paths,
- staticRRODirs []rroDir, deps android.Paths, flags []string, sdkLibraries []string) {
+ staticRRODirs []rroDir, assets, deps android.Paths, flags []string, sdkLibraries []string) {
var sharedLibs android.Paths
@@ -373,6 +398,9 @@
transitiveStaticLibs = append(transitiveStaticLibs, exportPackage)
transitiveStaticLibManifests = append(transitiveStaticLibManifests, aarDep.ExportedManifests()...)
sdkLibraries = append(sdkLibraries, aarDep.ExportedSdkLibs()...)
+ if aarDep.ExportedAssets().Valid() {
+ assets = append(assets, aarDep.ExportedAssets().Path())
+ }
outer:
for _, d := range aarDep.ExportedRRODirs() {
@@ -402,7 +430,7 @@
transitiveStaticLibManifests = android.FirstUniquePaths(transitiveStaticLibManifests)
sdkLibraries = android.FirstUniqueStrings(sdkLibraries)
- return transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, deps, flags, sdkLibraries
+ return transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assets, deps, flags, sdkLibraries
}
type AndroidLibrary struct {
@@ -572,6 +600,11 @@
return android.Paths{a.manifest}
}
+// TODO(jungjw): Decide whether we want to implement this.
+func (a *AARImport) ExportedAssets() android.OptionalPath {
+ return android.OptionalPath{}
+}
+
func (a *AARImport) Prebuilt() *android.Prebuilt {
return &a.prebuilt
}
@@ -660,7 +693,7 @@
linkFlags = append(linkFlags, "--manifest "+a.manifest.String())
linkDeps = append(linkDeps, a.manifest)
- transitiveStaticLibs, staticLibManifests, staticRRODirs, libDeps, libFlags, sdkLibraries :=
+ transitiveStaticLibs, staticLibManifests, staticRRODirs, transitiveAssets, libDeps, libFlags, sdkLibraries :=
aaptLibs(ctx, sdkContext(a))
_ = staticLibManifests
@@ -673,7 +706,7 @@
overlayRes := append(android.Paths{flata}, transitiveStaticLibs...)
aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile,
- linkFlags, linkDeps, nil, overlayRes, nil)
+ linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil)
}
var _ Dependency = (*AARImport)(nil)
diff --git a/java/app_test.go b/java/app_test.go
index c20a8e7..c86b038 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -323,6 +323,107 @@
}
}
+func TestLibraryAssets(t *testing.T) {
+ bp := `
+ android_app {
+ name: "foo",
+ sdk_version: "current",
+ static_libs: ["lib1", "lib2", "lib3"],
+ }
+
+ android_library {
+ name: "lib1",
+ sdk_version: "current",
+ asset_dirs: ["assets_a"],
+ }
+
+ android_library {
+ name: "lib2",
+ sdk_version: "current",
+ }
+
+ android_library {
+ name: "lib3",
+ sdk_version: "current",
+ static_libs: ["lib4"],
+ }
+
+ android_library {
+ name: "lib4",
+ sdk_version: "current",
+ asset_dirs: ["assets_b"],
+ }
+ `
+
+ testCases := []struct {
+ name string
+ assetFlag string
+ assetPackages []string
+ }{
+ {
+ name: "foo",
+ // lib1 has its own asset. lib3 doesn't have any, but provides lib4's transitively.
+ assetPackages: []string{
+ buildDir + "/.intermediates/foo/android_common/aapt2/package-res.apk",
+ buildDir + "/.intermediates/lib1/android_common/assets.zip",
+ buildDir + "/.intermediates/lib3/android_common/assets.zip",
+ },
+ },
+ {
+ name: "lib1",
+ assetFlag: "-A assets_a",
+ },
+ {
+ name: "lib2",
+ },
+ {
+ name: "lib3",
+ assetPackages: []string{
+ buildDir + "/.intermediates/lib3/android_common/aapt2/package-res.apk",
+ buildDir + "/.intermediates/lib4/android_common/assets.zip",
+ },
+ },
+ {
+ name: "lib4",
+ assetFlag: "-A assets_b",
+ },
+ }
+ ctx := testApp(t, bp)
+
+ for _, test := range testCases {
+ t.Run(test.name, func(t *testing.T) {
+ m := ctx.ModuleForTests(test.name, "android_common")
+
+ // Check asset flag in aapt2 link flags
+ var aapt2link android.TestingBuildParams
+ if len(test.assetPackages) > 0 {
+ aapt2link = m.Output("aapt2/package-res.apk")
+ } else {
+ aapt2link = m.Output("package-res.apk")
+ }
+ aapt2Flags := aapt2link.Args["flags"]
+ if test.assetFlag != "" {
+ if !strings.Contains(aapt2Flags, test.assetFlag) {
+ t.Errorf("Can't find asset flag %q in aapt2 link flags %q", test.assetFlag, aapt2Flags)
+ }
+ } else {
+ if strings.Contains(aapt2Flags, " -A ") {
+ t.Errorf("aapt2 link flags %q contain unexpected asset flag", aapt2Flags)
+ }
+ }
+
+ // Check asset merge rule.
+ if len(test.assetPackages) > 0 {
+ mergeAssets := m.Output("package-res.apk")
+ if !reflect.DeepEqual(test.assetPackages, mergeAssets.Inputs.Strings()) {
+ t.Errorf("Unexpected mergeAssets inputs: %v, expected: %v",
+ mergeAssets.Inputs.Strings(), test.assetPackages)
+ }
+ }
+ })
+ }
+}
+
func TestAndroidResources(t *testing.T) {
testCases := []struct {
name string
diff --git a/java/droiddoc.go b/java/droiddoc.go
index abdceba..098400b 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -223,6 +223,9 @@
// if set to true, generate docs through Dokka instead of Doclava.
Dokka_enabled *bool
+
+ // Compat config XML. Generates compat change documentation if set.
+ Compat_config *string `android:"path"`
}
type DroidstubsProperties struct {
@@ -1037,6 +1040,11 @@
cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
+ if d.properties.Compat_config != nil {
+ compatConfig := android.PathForModuleSrc(ctx, String(d.properties.Compat_config))
+ cmd.FlagWithInput("-compatconfig ", compatConfig)
+ }
+
var desc string
if Bool(d.properties.Dokka_enabled) {
desc = "dokka"
diff --git a/java/java.go b/java/java.go
index ed3dca9..a4e91ab 100644
--- a/java/java.go
+++ b/java/java.go
@@ -757,9 +757,12 @@
type linkType int
const (
+ // TODO(jiyong) rename these for better readability. Make the allowed
+ // and disallowed link types explicit
javaCore linkType = iota
javaSdk
javaSystem
+ javaModule
javaPlatform
)
@@ -789,6 +792,10 @@
return javaSdk, true
case ver.kind == sdkPublic:
return javaSdk, false
+ case name == "android_module_lib_stubs_current":
+ return javaModule, true
+ case ver.kind == sdkModule:
+ return javaModule, false
case ver.kind == sdkPrivate || ver.kind == sdkNone || ver.kind == sdkCorePlatform:
return javaPlatform, false
case !ver.valid():
@@ -824,11 +831,17 @@
}
break
case javaSystem:
- if otherLinkType == javaPlatform {
+ if otherLinkType == javaPlatform || otherLinkType == javaModule {
ctx.ModuleErrorf("compiles against system API, but dependency %q is compiling against private API."+commonMessage,
ctx.OtherModuleName(to))
}
break
+ case javaModule:
+ if otherLinkType == javaPlatform {
+ ctx.ModuleErrorf("compiles against module API, but dependency %q is compiling against private API."+commonMessage,
+ ctx.OtherModuleName(to))
+ }
+ break
case javaPlatform:
// no restriction on link-type
break
diff --git a/java/java_test.go b/java/java_test.go
index 0e987a6..8815c09 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1099,6 +1099,12 @@
libs: ["foo"],
sdk_version: "test_current",
}
+ java_library {
+ name: "baz-29",
+ srcs: ["c.java"],
+ libs: ["foo"],
+ sdk_version: "system_29",
+ }
`)
// check the existence of the internal modules
@@ -1138,6 +1144,13 @@
"foo.stubs.test.jar")
}
+ baz29Javac := ctx.ModuleForTests("baz-29", "android_common").Rule("javac")
+ // tests if baz-29 is actually linked to the system 29 stubs lib
+ if !strings.Contains(baz29Javac.Args["classpath"], "prebuilts/sdk/29/system/foo.jar") {
+ t.Errorf("baz-29 javac classpath %v does not contain %q", baz29Javac.Args["classpath"],
+ "prebuilts/sdk/29/system/foo.jar")
+ }
+
// test if baz has exported SDK lib names foo and bar to qux
qux := ctx.ModuleForTests("qux", "android_common")
if quxLib, ok := qux.Module().(*Library); ok {
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index d5c7579..cb8e684 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -16,11 +16,17 @@
import (
"android/soong/android"
+ "fmt"
)
func init() {
android.RegisterSingletonType("platform_compat_config_singleton", platformCompatConfigSingletonFactory)
- android.RegisterModuleType("platform_compat_config", platformCompatConfigFactory)
+ android.RegisterModuleType("platform_compat_config", PlatformCompatConfigFactory)
+ android.RegisterModuleType("global_compat_config", globalCompatConfigFactory)
+}
+
+func platformCompatConfigPath(ctx android.PathContext) android.OutputPath {
+ return android.PathForOutput(ctx, "compat_config", "merged_compat_config.xml")
}
type platformCompatConfigSingleton struct {
@@ -44,11 +50,24 @@
return p.metadataFile
}
-type platformCompatConfigIntf interface {
- compatConfigMetadata() android.OutputPath
+func (p *platformCompatConfig) CompatConfig() android.OutputPath {
+ return p.configFile
}
-var _ platformCompatConfigIntf = (*platformCompatConfig)(nil)
+func (p *platformCompatConfig) SubDir() string {
+ return "compatconfig"
+}
+
+type PlatformCompatConfigIntf interface {
+ android.Module
+
+ compatConfigMetadata() android.OutputPath
+ CompatConfig() android.OutputPath
+ // Sub dir under etc dir.
+ SubDir() string
+}
+
+var _ PlatformCompatConfigIntf = (*platformCompatConfig)(nil)
// compat singleton rules
func (p *platformCompatConfigSingleton) GenerateBuildActions(ctx android.SingletonContext) {
@@ -56,7 +75,7 @@
var compatConfigMetadata android.Paths
ctx.VisitAllModules(func(module android.Module) {
- if c, ok := module.(platformCompatConfigIntf); ok {
+ if c, ok := module.(PlatformCompatConfigIntf); ok {
metadata := c.compatConfigMetadata()
compatConfigMetadata = append(compatConfigMetadata, metadata)
}
@@ -68,7 +87,7 @@
}
rule := android.NewRuleBuilder()
- outputPath := android.PathForOutput(ctx, "compat_config", "merged_compat_config.xml")
+ outputPath := platformCompatConfigPath(ctx)
rule.Command().
BuiltTool(ctx, "process-compat-config").
@@ -124,9 +143,55 @@
return &platformCompatConfigSingleton{}
}
-func platformCompatConfigFactory() android.Module {
+func PlatformCompatConfigFactory() android.Module {
module := &platformCompatConfig{}
module.AddProperties(&module.properties)
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
return module
}
+
+//============== merged_compat_config =================
+type globalCompatConfigProperties struct {
+ // name of the file into which the metadata will be copied.
+ Filename *string
+}
+
+type globalCompatConfig struct {
+ android.ModuleBase
+
+ properties globalCompatConfigProperties
+
+ outputFilePath android.OutputPath
+}
+
+func (c *globalCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ filename := String(c.properties.Filename)
+
+ inputPath := platformCompatConfigPath(ctx)
+ c.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath
+
+ // This ensures that outputFilePath has the correct name for others to
+ // use, as the source file may have a different name.
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Output: c.outputFilePath,
+ Input: inputPath,
+ })
+}
+
+func (h *globalCompatConfig) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ return android.Paths{h.outputFilePath}, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
+}
+
+// global_compat_config provides access to the merged compat config xml file generated by the build.
+func globalCompatConfigFactory() android.Module {
+ module := &globalCompatConfig{}
+ module.AddProperties(&module.properties)
+ android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
+ return module
+}
diff --git a/java/sdk.go b/java/sdk.go
index f388358..1c047a3 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -71,6 +71,7 @@
sdkPublic
sdkSystem
sdkTest
+ sdkModule
sdkPrivate
)
@@ -91,6 +92,8 @@
return "core"
case sdkCorePlatform:
return "core_platform"
+ case sdkModule:
+ return "module"
default:
return "invalid"
}
@@ -256,6 +259,8 @@
kind = sdkSystem
case "test":
kind = sdkTest
+ case "module":
+ kind = sdkModule
default:
return sdkSpec{sdkInvalid, sdkVersionNone, str}
}
@@ -382,6 +387,9 @@
return toModule("android_test_stubs_current", "framework-res", sdkFrameworkAidlPath(ctx))
case sdkCore:
return toModule("core.current.stubs", "", nil)
+ case sdkModule:
+ // TODO(146757305): provide .apk and .aidl that have more APIs for modules
+ return toModule("android_module_lib_stubs_current", "framework-res", sdkFrameworkAidlPath(ctx))
default:
panic(fmt.Errorf("invalid sdk %q", sdkVersion.raw))
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index cd22e6e..fb8ae95 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -683,8 +683,9 @@
sdkVersion sdkSpec,
headerJars bool) android.Paths {
- // This module is just a wrapper for the stubs.
- if ctx.Config().UnbundledBuildUsePrebuiltSdks() {
+ // If a specific numeric version has been requested or the build is explicitly configured
+ // for it then use prebuilt versions of the sdk.
+ if sdkVersion.version.isNumbered() || ctx.Config().UnbundledBuildUsePrebuiltSdks() {
return module.PrebuiltJars(ctx, sdkVersion)
} else {
if !sdkVersion.specified() {
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 9cabd77..c815fe3 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -211,6 +211,15 @@
java8classpath: []string{"prebuilts/sdk/29/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
aidl: "-pprebuilts/sdk/29/public/framework.aidl",
},
+ {
+
+ name: "module_current",
+ properties: `sdk_version: "module_current",`,
+ bootclasspath: []string{"android_module_lib_stubs_current", "core-lambda-stubs"},
+ system: "core-current-stubs-system-modules",
+ java9classpath: []string{"android_module_lib_stubs_current"},
+ aidl: "-p" + buildDir + "/framework.aidl",
+ },
}
for _, testcase := range classpathTestcases {
diff --git a/java/testing.go b/java/testing.go
index e746e2d..8f979c7 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -49,6 +49,8 @@
"api/test-current.txt": nil,
"api/test-removed.txt": nil,
"framework/aidl/a.aidl": nil,
+ "assets_a/a": nil,
+ "assets_b/b": nil,
"prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so": nil,
@@ -61,6 +63,7 @@
"prebuilts/sdk/29/public/android.jar": nil,
"prebuilts/sdk/29/public/framework.aidl": nil,
"prebuilts/sdk/29/system/android.jar": nil,
+ "prebuilts/sdk/29/system/foo.jar": nil,
"prebuilts/sdk/current/core/android.jar": nil,
"prebuilts/sdk/current/public/android.jar": nil,
"prebuilts/sdk/current/public/framework.aidl": nil,
@@ -143,6 +146,7 @@
"android_stubs_current",
"android_system_stubs_current",
"android_test_stubs_current",
+ "android_module_lib_stubs_current",
"core.current.stubs",
"core.platform.api.stubs",
"kotlin-stdlib",