Handle android_app_set in Soong built apkcerts.txt

android_app_set modules contain presigned apks, and uses `extract_apks`
to create an entry for each split apk in `LOCAL_APK_CERTS`, which then
gets concatenated to apkcerts.txt when built using Make.

This logic was previously not handled correctly in the new Soong
implementation, causing build errors in partner workspaces.

Bug: 396131789
Test: In partner-workspace, built the soong generated apkcerts.txt file
Change-Id: I7dd0dcd6c992660d5a7e7d484b5d83dc06e051f3
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index 443e80e..690b9e1 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -1046,6 +1046,7 @@
 	}
 
 	apkCerts := []string{}
+	var apkCertsFiles android.Paths
 	for _, installedModule := range allInstalledModules {
 		partition := ""
 		if commonInfo, ok := android.OtherModuleProvider(ctx, installedModule, android.CommonModuleInfoProvider); ok {
@@ -1054,7 +1055,11 @@
 			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))
+			if info.AppSet {
+				apkCertsFiles = append(apkCertsFiles, info.ApkCertsFile)
+			} else {
+				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 {
 				// Partition information of apk-in-apex is not exported to the legacy Make packaging system.
@@ -1075,7 +1080,14 @@
 		}
 	}
 
+	apkCertsInfoWithoutAppSets := android.PathForModuleOut(ctx, "apkcerts_without_app_sets.txt")
+	android.WriteFileRuleVerbatim(ctx, apkCertsInfoWithoutAppSets, strings.Join(apkCerts, "\n")+"\n")
 	apkCertsInfo := android.PathForModuleOut(ctx, "apkcerts.txt")
-	android.WriteFileRuleVerbatim(ctx, apkCertsInfo, strings.Join(apkCerts, "\n")+"\n")
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        android.Cat,
+		Description: "combine apkcerts.txt",
+		Output:      apkCertsInfo,
+		Inputs:      append(apkCertsFiles, apkCertsInfoWithoutAppSets),
+	})
 	return apkCertsInfo
 }
diff --git a/java/app.go b/java/app.go
index 560129b..8d4c3bb 100644
--- a/java/app.go
+++ b/java/app.go
@@ -82,6 +82,7 @@
 	Certificate                   Certificate
 	PrivAppAllowlist              android.OptionalPath
 	OverriddenManifestPackageName *string
+	ApkCertsFile                  android.Path
 }
 
 var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
diff --git a/java/app_set.go b/java/app_set.go
index 2e9d314..6a2c678 100644
--- a/java/app_set.go
+++ b/java/app_set.go
@@ -193,9 +193,10 @@
 	)
 
 	android.SetProvider(ctx, AppInfoProvider, &AppInfo{
-		AppSet:     true,
-		Privileged: as.Privileged(),
-		OutputFile: as.OutputFile(),
+		AppSet:       true,
+		Privileged:   as.Privileged(),
+		OutputFile:   as.OutputFile(),
+		ApkCertsFile: as.apkcertsFile,
 	})
 }