aboutsummaryrefslogtreecommitdiff
path: root/apex/prebuilt.go
diff options
context:
space:
mode:
Diffstat (limited to 'apex/prebuilt.go')
-rw-r--r--apex/prebuilt.go116
1 files changed, 72 insertions, 44 deletions
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index fdd9a75d7..7d9a128d6 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -15,7 +15,6 @@
package apex
import (
- "fmt"
"slices"
"sort"
"strconv"
@@ -48,6 +47,16 @@ var (
CommandDeps: []string{"${deapexer}"},
Description: "decompress $out",
})
+ // Compares the declared apps of `prebuilt_apex` with the actual apks
+ validateApkInPrebuiltApex = pctx.StaticRule("validateApkinPrebuiltApex", blueprint.RuleParams{
+ Command: `rm -rf ${out} ${actualApks} &&` +
+ ` ${apex_ls} ${in} | grep apk$$ | awk -F '/' '{print $$NF}' | sort -u > ${actualApks} &&` +
+ ` cmp -s ${expectedApks} ${actualApks} && touch ${out}` +
+ ` || (echo "Found diffs between "apps" property of ${apexName} and actual contents of ${in}.` +
+ ` Please ensure that all apk-in-apexes are declared in 'apps' property." && exit 1)`,
+ CommandDeps: []string{"${apex_ls}"},
+ Description: "validate apk in prebuilt_apex $out",
+ }, "expectedApks", "actualApks", "apexName")
)
type prebuilt interface {
@@ -335,19 +344,19 @@ func (m ApexPrebuiltDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.
}
func (p *prebuiltCommon) checkExportedDependenciesArePrebuilts(ctx android.ModuleContext) {
- ctx.VisitDirectDeps(func(dep android.Module) {
+ ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(dep)
depName := ctx.OtherModuleName(dep)
if exportedTag, ok := tag.(exportedDependencyTag); ok {
propertyName := exportedTag.name
// It is an error if the other module is not a prebuilt.
- if !android.IsModulePrebuilt(dep) {
+ if !android.IsModulePrebuilt(ctx, dep) {
ctx.PropertyErrorf(propertyName, "%q is not a prebuilt module", depName)
}
// It is an error if the other module is not an ApexModule.
- if _, ok := dep.(android.ApexModule); !ok {
+ if _, ok := android.OtherModuleProvider(ctx, dep, android.ApexInfoProvider); !ok {
ctx.PropertyErrorf(propertyName, "%q is not usable within an apex", depName)
}
}
@@ -370,8 +379,6 @@ type Prebuilt struct {
properties PrebuiltProperties
inputApex android.Path
-
- provenanceMetaDataFile android.Path
}
type ApexFileProperties struct {
@@ -483,7 +490,7 @@ func (p *prebuiltCommon) getDeapexerPropertiesIfNeeded(ctx android.ModuleContext
commonModules := []string{}
dexpreoptProfileGuidedModules := []string{}
exportedFiles := []string{}
- ctx.WalkDeps(func(child, parent android.Module) bool {
+ ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
tag := ctx.OtherModuleDependencyTag(child)
// If the child is not in the same apex as the parent then ignore it and all its children.
@@ -491,15 +498,14 @@ func (p *prebuiltCommon) getDeapexerPropertiesIfNeeded(ctx android.ModuleContext
return false
}
- name := java.ModuleStemForDeapexing(child)
+ name := java.ModuleStemForDeapexing(ctx, child)
if _, ok := tag.(android.RequiresFilesFromPrebuiltApexTag); ok {
commonModules = append(commonModules, name)
- extract := child.(android.RequiredFilesFromPrebuiltApex)
- requiredFiles := extract.RequiredFilesFromPrebuiltApex(ctx)
- exportedFiles = append(exportedFiles, requiredFiles...)
+ info := android.OtherModuleProviderOrDefault(ctx, child, android.RequiredFilesFromPrebuiltApexInfoProvider)
+ exportedFiles = append(exportedFiles, info.RequiredFilesFromPrebuiltApex...)
- if extract.UseProfileGuidedDexpreopt() {
+ if info.UseProfileGuidedDexpreopt {
dexpreoptProfileGuidedModules = append(dexpreoptProfileGuidedModules, name)
}
@@ -627,7 +633,7 @@ func (p *prebuiltCommon) provideApexExportsInfo(ctx android.ModuleContext, di *a
// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
// with information about whether source or prebuilt of an apex was used during the build.
func (p *prebuiltCommon) providePrebuiltInfo(ctx android.ModuleContext) {
- info := android.PrebuiltInfo{
+ info := android.PrebuiltJsonInfo{
Name: p.BaseModuleName(),
Is_prebuilt: true,
}
@@ -635,14 +641,14 @@ func (p *prebuiltCommon) providePrebuiltInfo(ctx android.ModuleContext) {
if p.prebuiltCommonProperties.Prebuilt_info != nil {
info.Prebuilt_info_file_path = android.PathForModuleSrc(ctx, *p.prebuiltCommonProperties.Prebuilt_info).String()
}
- android.SetProvider(ctx, android.PrebuiltInfoProvider, info)
+ android.SetProvider(ctx, android.PrebuiltJsonInfoProvider, info)
}
// Uses an object provided by its deps to validate that the contents of bcpf have been added to the global
// PRODUCT_APEX_BOOT_JARS
// This validation will only run on the apex which is active for this product/release_config
func validateApexClasspathFragments(ctx android.ModuleContext) {
- ctx.VisitDirectDeps(func(m android.Module) {
+ ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
if info, exists := android.OtherModuleProvider(ctx, m, java.ClasspathFragmentValidationInfoProvider); exists {
ctx.ModuleErrorf("%s in contents of %s must also be declared in PRODUCT_APEX_BOOT_JARS", info.UnknownJars, info.ClasspathFragmentModuleName)
}
@@ -701,7 +707,7 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
p.installApexSystemServerFiles(ctx)
installDeps := slices.Concat(p.compatSymlinks, p.extraInstalledFiles)
p.installedFile = ctx.InstallFile(p.installDir, p.installFilename, p.inputApex, installDeps...)
- p.provenanceMetaDataFile = provenance.GenerateArtifactProvenanceMetaData(ctx, p.inputApex, p.installedFile)
+ provenance.GenerateArtifactProvenanceMetaData(ctx, p.inputApex, p.installedFile)
}
p.addApkCertsInfo(ctx)
@@ -711,19 +717,40 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
android.SetProvider(ctx, filesystem.ApexKeyPathInfoProvider, filesystem.ApexKeyPathInfo{p.apexKeysPath})
}
-// `addApkCertsInfo` sets a provider that will be used to create apkcerts.txt
-func (p *Prebuilt) addApkCertsInfo(ctx android.ModuleContext) {
- formatLine := func(cert java.Certificate, name, partition string) string {
- pem := cert.AndroidMkString()
- var key string
- if cert.Key == nil {
- key = ""
- } else {
- key = cert.Key.String()
- }
- return fmt.Sprintf(`name="%s" certificate="%s" private_key="%s" partition="%s"`, name, pem, key, partition)
+// Creates a timestamp file that will be used to validate that there is no mismtach
+// between apks declared via `apps` and the actual apks inside the apex.
+func (p *Prebuilt) validateApkInPrebuiltApex(ctx android.ModuleContext, appInfos java.AppInfos) android.Path {
+ timestamp := android.PathForModuleOut(ctx, "apk_in_prebuilt_apex.timestamp")
+ // Create a list of expected installed apks.
+ var installedApks []string
+ for _, appInfo := range appInfos {
+ installedApks = append(installedApks, appInfo.InstallApkName+".apk")
+ }
+ expectedApksFile := android.PathForModuleOut(ctx, "expected_apk_in_prebuilt_apex.txt")
+ if len(installedApks) == 0 {
+ android.WriteFileRuleVerbatim(ctx, expectedApksFile, "") // Without newline
+ } else {
+ android.WriteFileRule(ctx, expectedApksFile, strings.Join(android.SortedUniqueStrings(installedApks), "\n")) // With newline
}
+ actualApksFile := android.PathForModuleOut(ctx, "actual_apk_in_prebuilt_apex.txt")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: validateApkInPrebuiltApex,
+ Input: p.inputApex,
+ Output: timestamp,
+ Implicit: expectedApksFile,
+ ImplicitOutput: actualApksFile,
+ Args: map[string]string{
+ "expectedApks": expectedApksFile.String(),
+ "actualApks": actualApksFile.String(),
+ "apexName": p.Name(),
+ },
+ })
+ return timestamp
+}
+
+// `addApkCertsInfo` sets a provider that will be used to create apkcerts.txt
+func (p *Prebuilt) addApkCertsInfo(ctx android.ModuleContext) {
// Determine if this prebuilt_apex contains any .apks
var appInfos java.AppInfos
ctx.VisitDirectDepsProxyWithTag(appInPrebuiltApexTag, func(app android.ModuleProxy) {
@@ -737,28 +764,29 @@ func (p *Prebuilt) addApkCertsInfo(ctx android.ModuleContext) {
return appInfos[i].InstallApkName < appInfos[j].InstallApkName
})
- if len(appInfos) == 0 {
- return
- }
-
- // Set a provider for use by `android_device`.
- // `android_device` will create an apkcerts.txt with the list of installed apps for that device.
- android.SetProvider(ctx, java.AppInfosProvider, appInfos)
-
- // Set a Make variable for legacy apkcerts.txt creation
- // p.apkCertsFile will become `LOCAL_APKCERTS_FILE`
+ // Create p.apkCertsFile with information about apk-in-apex
+ // p.apkCertsFile will become `LOCAL_APKCERTS_FILE` for Make packaging system
+ // p.apkCertsFile will be propagated to android_device for Soong packaging system
var lines []string
for _, appInfo := range appInfos {
- lines = append(lines, formatLine(appInfo.Certificate, appInfo.InstallApkName+".apk", p.PartitionTag(ctx.DeviceConfig())))
+ lines = append(lines, java.FormatApkCertsLine(appInfo.Certificate, appInfo.InstallApkName+".apk", p.PartitionTag(ctx.DeviceConfig())))
}
- if len(lines) > 0 {
- p.apkCertsFile = android.PathForModuleOut(ctx, "apkcerts.txt")
- android.WriteFileRule(ctx, p.apkCertsFile, strings.Join(lines, "\n"))
+ apkCertsFile := android.PathForModuleOut(ctx, "apkcerts.txt")
+ var validations android.Paths
+ if p.IsInstallable() {
+ // Skip the validation for non-installable prebuilt apexes (e.g. used in CTS tests).
+ validations = append(validations, p.validateApkInPrebuiltApex(ctx, appInfos))
}
-}
+ android.WriteFileRule(ctx, apkCertsFile, strings.Join(lines, "\n"), validations...)
-func (p *Prebuilt) ProvenanceMetaDataFile() android.Path {
- return p.provenanceMetaDataFile
+ // Skip exporting the apkcerts file if there were missing dependencies, because soong will
+ // cause all build rules of a module with missing dependencies to fail to build.
+ if len(ctx.GetMissingDependencies()) == 0 {
+ p.apkCertsFile = apkCertsFile
+ android.SetProvider(ctx, java.ApkCertInfoProvider, java.ApkCertInfo{
+ ApkCertsFile: p.apkCertsFile,
+ })
+ }
}
// extract registers the build actions to extract an apex from .apks file