Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d6c51eb authored by Jiyong Park's avatar Jiyong Park
Browse files

apex_sets is added to apexkeys.txt

apex_sets is a new module type that can be used to deliver pre-signed
APEXes, which previously could be done only via prebuilt_apex.

Soon gnow understands apex_sets module types and emits the signing info
of the modules to apexkeys.txt

Bug: 158729168
Test: m
Change-Id: I9507375342ec053309660d94c931a79bf4f21218
parent 7d95aac0
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -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)
@@ -5196,6 +5197,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()
+55 −21
Original line number Diff line number Diff line
@@ -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{
+4 −0
Original line number Diff line number Diff line
@@ -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{}