diff --git a/apex/apex_test.go b/apex/apex_test.go index 6df8f5989..c8dfe0e35 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -241,6 +241,7 @@ func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*andr java.RegisterSystemModulesBuildComponents(ctx) java.RegisterAppBuildComponents(ctx) ctx.RegisterModuleType("java_sdk_library", java.SdkLibraryFactory) + ctx.RegisterSingletonType("apex_keys_text", apexKeysTextFactory) ctx.PreDepsMutators(RegisterPreDepsMutators) ctx.PostDepsMutators(RegisterPostDepsMutators) @@ -5198,6 +5199,46 @@ func TestNoStaticLinkingToStubsLib(t *testing.T) { `) } +func TestApexKeysTxt(t *testing.T) { + ctx, _ := testApex(t, ` + apex { + name: "myapex", + key: "myapex.key", + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + prebuilt_apex { + name: "myapex", + prefer: true, + arch: { + arm64: { + src: "myapex-arm64.apex", + }, + arm: { + src: "myapex-arm.apex", + }, + }, + } + + apex_set { + name: "myapex_set", + set: "myapex.apks", + filename: "myapex_set.apex", + overrides: ["myapex"], + } + `) + + apexKeysText := ctx.SingletonForTests("apex_keys_text") + content := apexKeysText.MaybeDescription("apexkeys.txt").BuildParams.Args["content"] + ensureContains(t, content, `name="myapex_set.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`) + ensureNotContains(t, content, "myapex.apex") +} + func TestMain(m *testing.M) { run := func() int { setUp() diff --git a/apex/key.go b/apex/key.go index 607cac57c..a68f6e1a1 100644 --- a/apex/key.go +++ b/apex/key.go @@ -106,10 +106,36 @@ type apexKeysText struct { func (s *apexKeysText) GenerateBuildActions(ctx android.SingletonContext) { s.output = android.PathForOutput(ctx, "apexkeys.txt") - apexModulesMap := make(map[string]android.Module) + type apexKeyEntry struct { + name string + presigned bool + public_key string + private_key string + container_certificate string + container_private_key string + partition string + } + toString := func(e apexKeyEntry) string { + format := "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q partition=%q\\n" + if e.presigned { + return fmt.Sprintf(format, e.name, "PRESIGNED", "PRESIGNED", "PRESIGNED", "PRESIGNED", e.partition) + } else { + return fmt.Sprintf(format, e.name, e.public_key, e.private_key, e.container_certificate, e.container_private_key, e.partition) + } + } + + apexKeyMap := make(map[string]apexKeyEntry) ctx.VisitAllModules(func(module android.Module) { if m, ok := module.(*apexBundle); ok && m.Enabled() && m.installable() { - apexModulesMap[m.Name()] = m + apexKeyMap[m.Name()] = apexKeyEntry{ + name: m.Name() + ".apex", + presigned: false, + public_key: m.public_key_file.String(), + private_key: m.private_key_file.String(), + container_certificate: m.container_certificate_file.String(), + container_private_key: m.container_private_key_file.String(), + partition: m.PartitionTag(ctx.DeviceConfig()), + } } }) @@ -117,35 +143,43 @@ func (s *apexKeysText) GenerateBuildActions(ctx android.SingletonContext) { ctx.VisitAllModules(func(module android.Module) { if m, ok := module.(*Prebuilt); ok && m.Enabled() && m.installable() && m.Prebuilt().UsePrebuilt() { - apexModulesMap[m.BaseModuleName()] = m + apexKeyMap[m.BaseModuleName()] = apexKeyEntry{ + name: m.InstallFilename(), + presigned: true, + partition: m.PartitionTag(ctx.DeviceConfig()), + } + } + }) + + // Find apex_set and let them override apexBundle or prebuilts. This is done in a separate pass + // so that apex_set are not overridden by prebuilts. + ctx.VisitAllModules(func(module android.Module) { + if m, ok := module.(*ApexSet); ok && m.Enabled() { + entry := apexKeyEntry{ + name: m.InstallFilename(), + presigned: true, + partition: m.PartitionTag(ctx.DeviceConfig()), + } + + for _, om := range m.Overrides() { + if _, ok := apexKeyMap[om]; ok { + delete(apexKeyMap, om) + } + } + apexKeyMap[m.BaseModuleName()] = entry } }) // iterating over map does not give consistent ordering in golang var moduleNames []string - for key, _ := range apexModulesMap { + for key, _ := range apexKeyMap { moduleNames = append(moduleNames, key) } sort.Strings(moduleNames) var filecontent strings.Builder - for _, key := range moduleNames { - module := apexModulesMap[key] - if m, ok := module.(*apexBundle); ok { - fmt.Fprintf(&filecontent, - "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q partition=%q\\n", - m.Name()+".apex", - m.public_key_file.String(), - m.private_key_file.String(), - m.container_certificate_file.String(), - m.container_private_key_file.String(), - m.PartitionTag(ctx.DeviceConfig())) - } else if m, ok := module.(*Prebuilt); ok { - fmt.Fprintf(&filecontent, - "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q partition=%q\\n", - m.InstallFilename(), - "PRESIGNED", "PRESIGNED", "PRESIGNED", "PRESIGNED", m.PartitionTag(ctx.DeviceConfig())) - } + for _, name := range moduleNames { + fmt.Fprintf(&filecontent, "%s", toString(apexKeyMap[name])) } ctx.Build(pctx, android.BuildParams{ diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 03266c55e..bf574dc65 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -278,6 +278,10 @@ func (a *ApexSet) Name() string { return a.prebuilt.Name(a.ModuleBase.Name()) } +func (a *ApexSet) Overrides() []string { + return a.properties.Overrides +} + // prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex. func apexSetFactory() android.Module { module := &ApexSet{}