diff --git a/apex/apex.go b/apex/apex.go index 41c7a97fb..e6c4d8837 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -71,15 +71,17 @@ type dependencyTag struct { } var ( - sharedLibTag = dependencyTag{name: "sharedLib"} - executableTag = dependencyTag{name: "executable"} - javaLibTag = dependencyTag{name: "javaLib"} - prebuiltTag = dependencyTag{name: "prebuilt"} - keyTag = dependencyTag{name: "key"} + sharedLibTag = dependencyTag{name: "sharedLib"} + executableTag = dependencyTag{name: "executable"} + javaLibTag = dependencyTag{name: "javaLib"} + prebuiltTag = dependencyTag{name: "prebuilt"} + keyTag = dependencyTag{name: "key"} + certificateTag = dependencyTag{name: "certificate"} ) func init() { pctx.Import("android/soong/common") + pctx.Import("android/soong/java") pctx.HostBinToolVariable("apexer", "apexer") // ART minimal builds (using the master-art manifest) do not have the "frameworks/base" // projects, and hence cannot built 'aapt2'. Use the SDK prebuilt instead. @@ -188,6 +190,10 @@ type apexBundleProperties struct { // Name of the apex_key module that provides the private key to sign APEX Key *string + // The name of a certificate in the default certificate directory, blank to use the default product certificate, + // or an android_app_certificate module name in the form ":module". + Certificate *string + Multilib struct { First struct { // List of native libraries whose compile_multilib is "first" @@ -324,6 +330,11 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { return } ctx.AddDependency(ctx.Module(), keyTag, String(a.properties.Key)) + + cert := android.SrcIsModule(String(a.properties.Certificate)) + if cert != "" { + ctx.AddDependency(ctx.Module(), certificateTag, cert) + } } func getCopyManifestForNativeLibrary(cc *cc.Module) (fileToCopy android.Path, dirInApex string) { @@ -366,6 +377,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { copyManifest := make(map[android.Path]string) var keyFile android.Path + var certificate java.Certificate ctx.WalkDeps(func(child, parent android.Module) bool { if _, ok := parent.(*apexBundle); ok { @@ -412,6 +424,13 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { } else { ctx.PropertyErrorf("key", "%q is not an apex_key module", depName) } + case certificateTag: + if dep, ok := child.(*java.AndroidAppCertificate); ok { + certificate = dep.Certificate + return false + } else { + ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName) + } } } else { // indirect dependencies @@ -426,6 +445,18 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { return false }) + cert := String(a.properties.Certificate) + if cert != "" && android.SrcIsModule(cert) == "" { + defaultDir := ctx.Config().DefaultAppCertificateDir(ctx) + certificate = java.Certificate{ + defaultDir.Join(ctx, cert+".x509.pem"), + defaultDir.Join(ctx, cert+".pk8"), + } + } else if cert == "" { + pem, key := ctx.Config().DefaultAppCertificate(ctx) + certificate = java.Certificate{pem, key} + } + // files and dirs that will be created in apex var readOnlyPaths []string var executablePaths []string // this also includes dirs @@ -455,7 +486,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "manifest.json")) fileContexts := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.File_contexts, "file_contexts")) - a.outputFile = android.PathForModuleOut(ctx, a.ModuleBase.Name()+apexSuffix) + unsignedOutputFile := android.PathForModuleOut(ctx, a.ModuleBase.Name()+apexSuffix+".unsigned") filesToCopy := []android.Path{} for file := range copyManifest { @@ -479,7 +510,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.ModuleBuild(pctx, android.ModuleBuildParams{ Rule: apexRule, Implicits: implicitInputs, - Output: a.outputFile, + Output: unsignedOutputFile, Args: map[string]string{ "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir, "image_dir": android.PathForModuleOut(ctx, "image").String(), @@ -491,6 +522,17 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { }, }) + a.outputFile = android.PathForModuleOut(ctx, a.ModuleBase.Name()+apexSuffix) + ctx.Build(pctx, android.BuildParams{ + Rule: java.Signapk, + Description: "signapk", + Output: a.outputFile, + Input: unsignedOutputFile, + Args: map[string]string{ + "certificates": strings.Join([]string{certificate.Pem.String(), certificate.Key.String()}, " "), + }, + }) + a.installDir = android.PathForModuleInstall(ctx, "apex") } diff --git a/java/androidmk.go b/java/androidmk.go index 359594c12..e395c9be7 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -239,7 +239,7 @@ func (app *AndroidApp) AndroidMk() android.AndroidMkData { fmt.Fprintln(w, "LOCAL_PRIVILEGED_MODULE := true") } - fmt.Fprintln(w, "LOCAL_CERTIFICATE :=", app.certificate.pem.String()) + fmt.Fprintln(w, "LOCAL_CERTIFICATE :=", app.certificate.Pem.String()) if len(app.appProperties.Overrides) > 0 { fmt.Fprintln(w, "LOCAL_OVERRIDES_PACKAGES := "+strings.Join(app.appProperties.Overrides, " ")) } diff --git a/java/app.go b/java/app.go index db6c15ce5..7ca20cee6 100644 --- a/java/app.go +++ b/java/app.go @@ -76,7 +76,7 @@ type AndroidApp struct { Library aapt - certificate certificate + certificate Certificate appProperties appProperties @@ -99,8 +99,8 @@ func (a *AndroidApp) ExportedManifest() android.Path { var _ AndroidLibraryDependency = (*AndroidApp)(nil) -type certificate struct { - pem, key android.Path +type Certificate struct { + Pem, Key android.Path } func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { @@ -237,7 +237,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { dexJarFile = nil } - var certificates []certificate + var certificates []Certificate var jniJarFile android.WritablePath jniLibs, certificateDeps := a.collectAppDeps(ctx) @@ -262,16 +262,16 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { certificateDeps = certificateDeps[1:] } else if cert != "" { defaultDir := ctx.Config().DefaultAppCertificateDir(ctx) - a.certificate = certificate{ + a.certificate = Certificate{ defaultDir.Join(ctx, cert+".x509.pem"), defaultDir.Join(ctx, cert+".pk8"), } } else { pem, key := ctx.Config().DefaultAppCertificate(ctx) - a.certificate = certificate{pem, key} + a.certificate = Certificate{pem, key} } - certificates = append([]certificate{a.certificate}, certificateDeps...) + certificates = append([]Certificate{a.certificate}, certificateDeps...) packageFile := android.PathForModuleOut(ctx, "package.apk") CreateAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates) @@ -287,9 +287,9 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { } } -func (a *AndroidApp) collectAppDeps(ctx android.ModuleContext) ([]jniLib, []certificate) { +func (a *AndroidApp) collectAppDeps(ctx android.ModuleContext) ([]jniLib, []Certificate) { var jniLibs []jniLib - var certificates []certificate + var certificates []Certificate ctx.VisitDirectDeps(func(module android.Module) { otherName := ctx.OtherModuleName(module) @@ -313,7 +313,7 @@ func (a *AndroidApp) collectAppDeps(ctx android.ModuleContext) ([]jniLib, []cert } } else if tag == certificateTag { if dep, ok := module.(*AndroidAppCertificate); ok { - certificates = append(certificates, dep.certificate) + certificates = append(certificates, dep.Certificate) } else { ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName) } @@ -446,7 +446,7 @@ func AndroidTestHelperAppFactory() android.Module { type AndroidAppCertificate struct { android.ModuleBase properties AndroidAppCertificateProperties - certificate certificate + Certificate Certificate } type AndroidAppCertificateProperties struct { @@ -466,7 +466,7 @@ func (c *AndroidAppCertificate) DepsMutator(ctx android.BottomUpMutatorContext) func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) { cert := String(c.properties.Certificate) - c.certificate = certificate{ + c.Certificate = Certificate{ android.PathForModuleSrc(ctx, cert+".x509.pem"), android.PathForModuleSrc(ctx, cert+".pk8"), } diff --git a/java/app_builder.go b/java/app_builder.go index 75774443f..424aec85c 100644 --- a/java/app_builder.go +++ b/java/app_builder.go @@ -29,7 +29,7 @@ import ( ) var ( - signapk = pctx.AndroidStaticRule("signapk", + Signapk = pctx.AndroidStaticRule("signapk", blueprint.RuleParams{ Command: `${config.JavaCmd} -Djava.library.path=$$(dirname $signapkJniLibrary) ` + `-jar $signapkCmd $certificates $in $out`, @@ -63,7 +63,7 @@ var combineApk = pctx.AndroidStaticRule("combineApk", }) func CreateAppPackage(ctx android.ModuleContext, outputFile android.WritablePath, - resJarFile, jniJarFile, dexJarFile android.Path, certificates []certificate) { + resJarFile, jniJarFile, dexJarFile android.Path, certificates []Certificate) { unsignedApk := android.PathForModuleOut(ctx, "unsigned.apk") @@ -84,11 +84,11 @@ func CreateAppPackage(ctx android.ModuleContext, outputFile android.WritablePath var certificateArgs []string for _, c := range certificates { - certificateArgs = append(certificateArgs, c.pem.String(), c.key.String()) + certificateArgs = append(certificateArgs, c.Pem.String(), c.Key.String()) } ctx.Build(pctx, android.BuildParams{ - Rule: signapk, + Rule: Signapk, Description: "signapk", Output: outputFile, Input: unsignedApk,