Set LOCAL_CERTIFICATE for flattened apex APKs

Leaving out LOCAL_CERTIFICATE for flattened apex APKs causes
the apkcerts.txt to have empty keys for those APKs, which
confuses the signing tools.  Set LOCAL_CERTIFICATE for them.

Also refactor the Certificate support to avoid introducing
duplicated handling for presigned certificates.

Bug: 147765187
Test: m apkcerts-list
Change-Id: Ife07661761cd5a89c9f009b8ce041db4dff9ec54
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 8cb9896..8929910 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -163,6 +163,7 @@
 			fmt.Fprintln(w, "LOCAL_DEX_PREOPT := false")
 			fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk")
 		} else if fi.class == app {
+			fmt.Fprintln(w, "LOCAL_CERTIFICATE :=", fi.certificate.AndroidMkString())
 			// soong_app_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .apk  Therefore
 			// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
 			// we will have foo.apk.apk
diff --git a/apex/apex.go b/apex/apex.go
index ae93790..48cdedf 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -709,7 +709,8 @@
 	targetRequiredModuleNames []string
 	hostRequiredModuleNames   []string
 
-	jacocoReportClassesFile android.Path // only for javalibs and apps
+	jacocoReportClassesFile android.Path     // only for javalibs and apps
+	certificate             java.Certificate // only for apps
 }
 
 func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, moduleName string, installDir string, class apexFileClass, module android.Module) apexFile {
@@ -1198,6 +1199,7 @@
 	Privileged() bool
 	OutputFile() android.Path
 	JacocoReportClassesFile() android.Path
+	Certificate() java.Certificate
 }, pkgName string) apexFile {
 	appDir := "app"
 	if aapp.Privileged() {
@@ -1207,6 +1209,7 @@
 	fileToCopy := aapp.OutputFile()
 	af := newApexFile(ctx, fileToCopy, aapp.Name(), dirInApex, app, aapp)
 	af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
+	af.certificate = aapp.Certificate()
 	return af
 }
 
diff --git a/java/androidmk.go b/java/androidmk.go
index f28ae10..6d4d40b 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -663,11 +663,7 @@
 		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
 			func(entries *android.AndroidMkEntries) {
 				entries.SetBoolIfTrue("LOCAL_PRIVILEGED_MODULE", a.Privileged())
-				if a.certificate != nil {
-					entries.SetPath("LOCAL_CERTIFICATE", a.certificate.Pem)
-				} else {
-					entries.SetString("LOCAL_CERTIFICATE", "PRESIGNED")
-				}
+				entries.SetString("LOCAL_CERTIFICATE", a.certificate.AndroidMkString())
 				entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", a.properties.Overrides...)
 				if len(a.dexpreopter.builtInstalled) > 0 {
 					entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", a.dexpreopter.builtInstalled)
diff --git a/java/app.go b/java/app.go
index 2ed3d4d..a27996c 100755
--- a/java/app.go
+++ b/java/app.go
@@ -154,10 +154,25 @@
 	return a.outputFile
 }
 
+func (a *AndroidApp) Certificate() Certificate {
+	return a.certificate
+}
+
 var _ AndroidLibraryDependency = (*AndroidApp)(nil)
 
 type Certificate struct {
-	Pem, Key android.Path
+	Pem, Key  android.Path
+	presigned bool
+}
+
+var presignedCertificate = Certificate{presigned: true}
+
+func (c Certificate) AndroidMkString() string {
+	if c.presigned {
+		return "PRESIGNED"
+	} else {
+		return c.Pem.String()
+	}
 }
 
 func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -405,12 +420,15 @@
 		if certPropValue != "" {
 			defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
 			mainCert = Certificate{
-				defaultDir.Join(ctx, certPropValue+".x509.pem"),
-				defaultDir.Join(ctx, certPropValue+".pk8"),
+				Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
+				Key: defaultDir.Join(ctx, certPropValue+".pk8"),
 			}
 		} else {
 			pem, key := ctx.Config().DefaultAppCertificate(ctx)
-			mainCert = Certificate{pem, key}
+			mainCert = Certificate{
+				Pem: pem,
+				Key: key,
+			}
 		}
 		certificates = append([]Certificate{mainCert}, certificates...)
 	}
@@ -798,8 +816,8 @@
 func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	cert := String(c.properties.Certificate)
 	c.Certificate = Certificate{
-		android.PathForModuleSrc(ctx, cert+".x509.pem"),
-		android.PathForModuleSrc(ctx, cert+".pk8"),
+		Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
+		Key: android.PathForModuleSrc(ctx, cert+".pk8"),
 	}
 }
 
@@ -856,7 +874,7 @@
 	archVariants interface{}
 
 	outputFile  android.Path
-	certificate *Certificate
+	certificate Certificate
 
 	dexpreopter
 
@@ -1064,7 +1082,7 @@
 		if len(certificates) != 1 {
 			ctx.ModuleErrorf("Unexpected number of certificates were extracted: %q", certificates)
 		}
-		a.certificate = &certificates[0]
+		a.certificate = certificates[0]
 		signed := android.PathForModuleOut(ctx, "signed", ctx.ModuleName()+".apk")
 		SignAppPackage(ctx, signed, dexOutput, certificates)
 		a.outputFile = signed
@@ -1072,6 +1090,7 @@
 		alignedApk := android.PathForModuleOut(ctx, "zip-aligned", ctx.ModuleName()+".apk")
 		TransformZipAlign(ctx, alignedApk, dexOutput)
 		a.outputFile = alignedApk
+		a.certificate = presignedCertificate
 	}
 
 	// TODO: Optionally compress the output apk.
@@ -1098,6 +1117,10 @@
 	return nil
 }
 
+func (a *AndroidAppImport) Certificate() Certificate {
+	return a.certificate
+}
+
 var dpiVariantGroupType reflect.Type
 var archVariantGroupType reflect.Type