diff options
Diffstat (limited to 'filesystem')
-rw-r--r-- | filesystem/android_device.go | 150 | ||||
-rw-r--r-- | filesystem/filesystem.go | 6 |
2 files changed, 146 insertions, 10 deletions
diff --git a/filesystem/android_device.go b/filesystem/android_device.go index c49e53686..04eaf840e 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -107,11 +107,15 @@ type androidDevice struct { allImagesZip android.Path - proguardDictZip android.Path - proguardDictMapping android.Path - proguardUsageZip android.Path - kernelConfig android.Path - kernelVersion android.Path + proguardDictZip android.Path + proguardDictMapping android.Path + proguardUsageZip android.Path + kernelConfig android.Path + kernelVersion android.Path + miscInfo android.Path + rootDirForFsConfig string + rootDirForFsConfigTimestamp android.Path + apkCertsInfo android.Path } func AndroidDeviceFactory() android.Module { @@ -186,7 +190,9 @@ func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) { allInstalledModules := a.allInstalledModules(ctx) + a.apkCertsInfo = a.buildApkCertsInfo(ctx, allInstalledModules) a.kernelConfig, a.kernelVersion = a.extractKernelVersionAndConfigs(ctx) + a.miscInfo = a.addMiscInfo(ctx) a.buildTargetFilesZip(ctx, allInstalledModules) a.buildProguardZips(ctx, allInstalledModules) @@ -359,6 +365,10 @@ func (a *androidDevice) distFiles(ctx android.ModuleContext) { ctx.DistForGoalWithFilename("droidcore-unbundled", a.proguardDictZip, namePrefix+insertBeforeExtension(a.proguardDictZip.Base(), "-FILE_NAME_TAG_PLACEHOLDER")) ctx.DistForGoalWithFilename("droidcore-unbundled", a.proguardDictMapping, namePrefix+insertBeforeExtension(a.proguardDictMapping.Base(), "-FILE_NAME_TAG_PLACEHOLDER")) ctx.DistForGoalWithFilename("droidcore-unbundled", a.proguardUsageZip, namePrefix+insertBeforeExtension(a.proguardUsageZip.Base(), "-FILE_NAME_TAG_PLACEHOLDER")) + + if a.deviceProps.Android_info != nil { + ctx.DistForGoal("droidcore-unbundled", android.PathForModuleSrc(ctx, *a.deviceProps.Android_info)) + } } } @@ -496,6 +506,17 @@ func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstal if toCopy.destSubdir == "SYSTEM" { // Create the ROOT partition in target_files.zip builder.Command().Textf("rsync --links --exclude=system/* %s/ -r %s/ROOT", toCopy.fsInfo.RootDir, targetFilesDir.String()) + // Add a duplicate rule to assemble the ROOT/ directory in separate intermediates. + // The output timestamp will be an input to a separate fs_config call. + a.rootDirForFsConfig = android.PathForModuleOut(ctx, "root_dir_for_fs_config").String() + rootDirBuilder := android.NewRuleBuilder(pctx, ctx) + rootDirForFsConfigTimestamp := android.PathForModuleOut(ctx, "root_dir_for_fs_config.timestamp") + rootDirBuilder.Command().Textf("rsync --links --exclude=system/* %s/ -r %s", toCopy.fsInfo.RootDir, a.rootDirForFsConfig). + Implicit(toCopy.fsInfo.Output). + Text("&& touch"). + Output(rootDirForFsConfigTimestamp) + rootDirBuilder.Build("assemble_root_dir_for_fs_config", "Assemble ROOT/ for fs_config") + a.rootDirForFsConfigTimestamp = rootDirForFsConfigTimestamp } } // Copy cmdline, kernel etc. files of boot images @@ -634,11 +655,11 @@ func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, build } if partition == "system" { // Create root_filesystem_config from the assembled ROOT/ intermediates directory - a.generateFilesystemConfigForTargetFiles(ctx, builder, targetFilesDir.String(), targetFilesDir.String()+"/ROOT", "root_filesystem_config.txt") + a.generateFilesystemConfigForTargetFiles(ctx, builder, a.rootDirForFsConfigTimestamp, targetFilesDir.String(), a.rootDirForFsConfig, "root_filesystem_config.txt") } if partition == "vendor_ramdisk" { // Create vendor_boot_filesystem_config from the assembled VENDOR_BOOT/RAMDISK intermediates directory - a.generateFilesystemConfigForTargetFiles(ctx, builder, targetFilesDir.String(), targetFilesDir.String()+"/VENDOR_BOOT/RAMDISK", "vendor_boot_filesystem_config.txt") + a.generateFilesystemConfigForTargetFiles(ctx, builder, nil, targetFilesDir.String(), targetFilesDir.String()+"/VENDOR_BOOT/RAMDISK", "vendor_boot_filesystem_config.txt") } } // Copy ramdisk_node_list @@ -658,6 +679,9 @@ func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, build } installedApexKeys = android.SortedUniquePaths(installedApexKeys) // Sort by keypath to match make builder.Command().Text("cat").Inputs(installedApexKeys).Textf(" >> %s/META/apexkeys.txt", targetFilesDir.String()) + // apkcerts.txt + builder.Command().Textf("cp").Input(a.apkCertsInfo).Textf(" %s/META/", targetFilesDir.String()) + // Copy fastboot-info.txt if fastbootInfo := android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.FastbootInfo)); fastbootInfo != nil { // TODO (b/399788523): Autogenerate fastboot-info.txt if there is no source fastboot-info.txt @@ -672,6 +696,12 @@ func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, build if a.kernelVersion != nil { builder.Command().Textf("cp").Input(a.kernelVersion).Textf(" %s/META/", targetFilesDir.String()) } + // misc_info.txt + if a.miscInfo != nil { + builder.Command().Textf("cp").Input(a.miscInfo).Textf(" %s/META/", targetFilesDir.String()) + } + // apex_info.pb, care_map.pb, vbmeta_digest.txt + a.addImgToTargetFiles(ctx, builder, targetFilesDir.String()) if a.partitionProps.Super_partition_name != nil { superPartition := ctx.GetDirectDepProxyWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag) @@ -686,17 +716,71 @@ func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, build } +// A partial implementation of make's $PRODUCT_OUT/misc_info.txt +// https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=5894?q=misc_info.txt%20f:build%2Fmake%2Fcore%2FMakefile&ss=android%2Fplatform%2Fsuperproject%2Fmain +// This file is subsequently used by add_img_to_target_files to create additioanl metadata files like apex_info.pb +// TODO (b/399788119): Complete the migration of misc_info.txt +func (a *androidDevice) addMiscInfo(ctx android.ModuleContext) android.Path { + builder := android.NewRuleBuilder(pctx, ctx) + miscInfo := android.PathForModuleOut(ctx, "misc_info.txt") + builder.Command(). + Textf("rm -f %s", miscInfo). + Textf("&& echo recovery_api_version=%s >> %s", ctx.Config().VendorConfig("recovery").String("recovery_api_version"), miscInfo). + Textf("&& echo fstab_version=%s >> %s", ctx.Config().VendorConfig("recovery").String("recovery_fstab_version"), miscInfo). + ImplicitOutput(miscInfo) + + if a.partitionProps.Recovery_partition_name == nil { + builder.Command().Textf("echo no_recovery=true >> %s", miscInfo) + } + fsInfos := a.getFsInfos(ctx) + for _, partition := range android.SortedKeys(fsInfos) { + if fsInfos[partition].UseAvb { + builder.Command().Textf("echo 'avb_%s_hashtree_enable=true' >> %s", partition, miscInfo) + } + } + if len(a.partitionProps.Vbmeta_partitions) > 0 { + builder.Command(). + Textf("echo avb_enable=true >> %s", miscInfo). + Textf("&& echo avb_building_vbmeta_image=true >> %s", miscInfo). + Textf("&& echo avb_avbtool=avbtool >> %s", miscInfo) + } + if a.partitionProps.Boot_partition_name != nil { + builder.Command().Textf("echo boot_images=boot.img >> %s", miscInfo) + } + + builder.Build("misc_info", "Building misc_info") + + return miscInfo +} + +// addImgToTargetFiles invokes `add_img_to_target_files` and creates the following files in META/ +// - apex_info.pb +// - care_map.pb +// - vbmeta_digest.txt +func (a *androidDevice) addImgToTargetFiles(ctx android.ModuleContext, builder *android.RuleBuilder, targetFilesDir string) { + mkbootimg := ctx.Config().HostToolPath(ctx, "mkbootimg") + builder.Command(). + Textf("PATH=%s:$PATH", ctx.Config().HostToolDir()). + Textf("MKBOOTIMG=%s", mkbootimg). + Implicit(mkbootimg). + BuiltTool("add_img_to_target_files"). + Flag("-a -v -p"). + Flag(ctx.Config().HostToolDir()). + Text(targetFilesDir) +} + type ApexKeyPathInfo struct { ApexKeyPath android.Path } var ApexKeyPathInfoProvider = blueprint.NewProvider[ApexKeyPathInfo]() -func (a *androidDevice) generateFilesystemConfigForTargetFiles(ctx android.ModuleContext, builder *android.RuleBuilder, targetFilesDir, stagingDir, filename string) { +func (a *androidDevice) generateFilesystemConfigForTargetFiles(ctx android.ModuleContext, builder *android.RuleBuilder, stagingDirTimestamp android.Path, targetFilesDir, stagingDir, filename string) { fsConfigOut := android.PathForModuleOut(ctx, filename) ctx.Build(pctx, android.BuildParams{ - Rule: fsConfigRule, - Output: fsConfigOut, + Rule: fsConfigRule, + Implicit: stagingDirTimestamp, + Output: fsConfigOut, Args: map[string]string{ "rootDir": stagingDir, "prefix": "", @@ -811,3 +895,49 @@ func (a *androidDevice) extractKernelVersionAndConfigs(ctx android.ModuleContext return extractedVersionFile, extractedConfigsFile } + +func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalledModules []android.Module) android.Path { + // TODO (spandandas): Add compressed + 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) + } + + apkCerts := []string{} + for _, installedModule := range allInstalledModules { + partition := "" + if commonInfo, ok := android.OtherModuleProvider(ctx, installedModule, android.CommonModuleInfoKey); ok { + partition = commonInfo.PartitionTag + } else { + ctx.ModuleErrorf("%s does not set CommonModuleInfoKey", installedModule.Name()) + } + if info, ok := android.OtherModuleProvider(ctx, installedModule, java.AppInfoProvider); ok { + apkCerts = append(apkCerts, formatLine(info.Certificate, info.InstallApkName+".apk", partition)) + } else if info, ok := android.OtherModuleProvider(ctx, installedModule, java.AppInfosProvider); ok { + for _, certInfo := range info { + apkCerts = append(apkCerts, formatLine(certInfo.Certificate, certInfo.InstallApkName+".apk", partition)) + } + } else if info, ok := android.OtherModuleProvider(ctx, installedModule, java.RuntimeResourceOverlayInfoProvider); ok { + apkCerts = append(apkCerts, formatLine(info.Certificate, info.OutputFile.Base(), partition)) + } + } + slices.Sort(apkCerts) // sort by name + fsInfos := a.getFsInfos(ctx) + if fsInfos["system"].HasFsverity { + defaultPem, defaultKey := ctx.Config().DefaultAppCertificate(ctx) + apkCerts = append(apkCerts, formatLine(java.Certificate{Pem: defaultPem, Key: defaultKey}, "BuildManifest.apk", "system")) + if info, ok := fsInfos["system_ext"]; ok && info.HasFsverity { + apkCerts = append(apkCerts, formatLine(java.Certificate{Pem: defaultPem, Key: defaultKey}, "BuildManifestSystemExt.apk", "system_ext")) + } + } + + apkCertsInfo := android.PathForModuleOut(ctx, "apkcerts.txt") + android.WriteFileRuleVerbatim(ctx, apkCertsInfo, strings.Join(apkCerts, "\n")+"\n") + return apkCertsInfo +} diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 88de21792..79db988a0 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -436,6 +436,10 @@ type FilesystemInfo struct { FilesystemConfig android.Path Owners []InstalledModuleInfo + + UseAvb bool + + HasFsverity bool } // FullInstallPathInfo contains information about the "full install" paths of all the files @@ -680,6 +684,8 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { SelinuxFc: f.selinuxFc, FilesystemConfig: f.generateFilesystemConfig(ctx, rootDir, rebasedDir), Owners: f.gatherOwners(specs), + UseAvb: proptools.Bool(f.properties.Use_avb), + HasFsverity: f.properties.Fsverity.Inputs.GetOrDefault(ctx, nil) != nil, } android.SetProvider(ctx, FilesystemProvider, fsInfo) |