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

Commit b14f2f06 authored by Paul Duffin's avatar Paul Duffin Committed by Gerrit Code Review
Browse files

Merge "Separate apex extraction from the ApexSet"

parents 1cec1104 2470467d
Loading
Loading
Loading
Loading
+18 −19
Original line number Diff line number Diff line
@@ -6368,7 +6368,6 @@ func TestAppSetBundle(t *testing.T) {
}

func TestAppSetBundlePrebuilt(t *testing.T) {
	ctx := testApex(t, "", android.FixtureModifyMockFS(func(fs android.MockFS) {
	bp := `
		apex_set {
			name: "myapex",
@@ -6377,24 +6376,23 @@ func TestAppSetBundlePrebuilt(t *testing.T) {
				none: { set: "myapex.apks", },
				hwaddress: { set: "myapex.hwasan.apks", },
			},
		}`
		fs["Android.bp"] = []byte(bp)
	}),
		prepareForTestWithSantitizeHwaddress,
	)
		}
	`
	ctx := testApex(t, bp, prepareForTestWithSantitizeHwaddress)

	m := ctx.ModuleForTests("myapex", "android_common")
	extractedApex := m.Output("out/soong/.intermediates/myapex/android_common/foo_v2.apex")
	// Check that the extractor produces the correct output file from the correct input file.
	extractorOutput := "out/soong/.intermediates/myapex.apex.extractor/android_common/extracted/myapex.hwasan.apks"

	actual := extractedApex.Inputs
	if len(actual) != 1 {
		t.Errorf("expected a single input")
	}
	m := ctx.ModuleForTests("myapex.apex.extractor", "android_common")
	extractedApex := m.Output(extractorOutput)

	expected := "myapex.hwasan.apks"
	if actual[0].String() != expected {
		t.Errorf("expected %s, got %s", expected, actual[0].String())
	}
	android.AssertArrayString(t, "extractor input", []string{"myapex.hwasan.apks"}, extractedApex.Inputs.Strings())

	// Ditto for the apex.
	m = ctx.ModuleForTests("myapex", "android_common")
	copiedApex := m.Output("out/soong/.intermediates/myapex/android_common/foo_v2.apex")

	android.AssertStringEquals(t, "myapex input", extractorOutput, copiedApex.Input.String())
}

func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) {
@@ -7030,10 +7028,10 @@ func TestApexSet(t *testing.T) {
		}),
	)

	m := ctx.ModuleForTests("myapex", "android_common")
	m := ctx.ModuleForTests("myapex.apex.extractor", "android_common")

	// Check extract_apks tool parameters.
	extractedApex := m.Output("out/soong/.intermediates/myapex/android_common/foo_v2.apex")
	extractedApex := m.Output("extracted/myapex.apks")
	actual := extractedApex.Args["abis"]
	expected := "ARMEABI_V7A,ARM64_V8A"
	if actual != expected {
@@ -7045,6 +7043,7 @@ func TestApexSet(t *testing.T) {
		t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual)
	}

	m = ctx.ModuleForTests("myapex", "android_common")
	a := m.Module().(*ApexSet)
	expectedOverrides := []string{"foo"}
	actualOverrides := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_OVERRIDES_MODULES"]
+109 −43
Original line number Diff line number Diff line
@@ -515,6 +515,49 @@ func (p *Prebuilt) AndroidMkEntries() []android.AndroidMkEntries {
	}}
}

// prebuiltApexExtractorModule is a private module type that is only created by the prebuilt_apex
// module. It extracts the correct apex to use and makes it available for use by apex_set.
type prebuiltApexExtractorModule struct {
	android.ModuleBase

	properties ApexExtractorProperties

	extractedApex android.WritablePath
}

func privateApexExtractorModuleFactory() android.Module {
	module := &prebuiltApexExtractorModule{}
	module.AddProperties(
		&module.properties,
	)
	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
	return module
}

func (p *prebuiltApexExtractorModule) Srcs() android.Paths {
	return android.Paths{p.extractedApex}
}

func (p *prebuiltApexExtractorModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	srcsSupplier := func(ctx android.BaseModuleContext, prebuilt android.Module) []string {
		return p.properties.prebuiltSrcs(ctx)
	}
	apexSet := android.SingleSourcePathFromSupplier(ctx, srcsSupplier, "set")
	p.extractedApex = android.PathForModuleOut(ctx, "extracted", apexSet.Base())
	ctx.Build(pctx,
		android.BuildParams{
			Rule:        extractMatchingApex,
			Description: "Extract an apex from an apex set",
			Inputs:      android.Paths{apexSet},
			Output:      p.extractedApex,
			Args: map[string]string{
				"abis":              strings.Join(java.SupportedAbis(ctx), ","),
				"allow-prereleased": strconv.FormatBool(proptools.Bool(p.properties.Prerelease)),
				"sdk-version":       ctx.Config().PlatformSdkVersion().String(),
			},
		})
}

type ApexSet struct {
	android.ModuleBase
	prebuiltCommon
@@ -533,7 +576,7 @@ type ApexSet struct {
	postInstallCommands []string
}

type ApexSetProperties struct {
type ApexExtractorProperties struct {
	// the .apks file path that contains prebuilt apex files to be extracted.
	Set *string

@@ -549,28 +592,14 @@ type ApexSetProperties struct {
		}
	}

	// whether the extracted apex file installable.
	Installable *bool

	// optional name for the installed apex. If unspecified, name of the
	// module is used as the file name
	Filename *string

	// names of modules to be overridden. Listed modules can only be other binaries
	// (in Make or Soong).
	// This does not completely prevent installation of the overridden binaries, but if both
	// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
	// from PRODUCT_PACKAGES.
	Overrides []string

	// apexes in this set use prerelease SDK version
	Prerelease *bool
}

func (a *ApexSet) prebuiltSrcs(ctx android.BaseModuleContext) []string {
func (e *ApexExtractorProperties) prebuiltSrcs(ctx android.BaseModuleContext) []string {
	var srcs []string
	if a.properties.Set != nil {
		srcs = append(srcs, *a.properties.Set)
	if e.Set != nil {
		srcs = append(srcs, *e.Set)
	}

	var sanitizers []string
@@ -580,17 +609,35 @@ func (a *ApexSet) prebuiltSrcs(ctx android.BaseModuleContext) []string {
		sanitizers = ctx.Config().SanitizeDevice()
	}

	if android.InList("address", sanitizers) && a.properties.Sanitized.Address.Set != nil {
		srcs = append(srcs, *a.properties.Sanitized.Address.Set)
	} else if android.InList("hwaddress", sanitizers) && a.properties.Sanitized.Hwaddress.Set != nil {
		srcs = append(srcs, *a.properties.Sanitized.Hwaddress.Set)
	} else if a.properties.Sanitized.None.Set != nil {
		srcs = append(srcs, *a.properties.Sanitized.None.Set)
	if android.InList("address", sanitizers) && e.Sanitized.Address.Set != nil {
		srcs = append(srcs, *e.Sanitized.Address.Set)
	} else if android.InList("hwaddress", sanitizers) && e.Sanitized.Hwaddress.Set != nil {
		srcs = append(srcs, *e.Sanitized.Hwaddress.Set)
	} else if e.Sanitized.None.Set != nil {
		srcs = append(srcs, *e.Sanitized.None.Set)
	}

	return srcs
}

type ApexSetProperties struct {
	ApexExtractorProperties

	// whether the extracted apex file installable.
	Installable *bool

	// optional name for the installed apex. If unspecified, name of the
	// module is used as the file name
	Filename *string

	// names of modules to be overridden. Listed modules can only be other binaries
	// (in Make or Soong).
	// This does not completely prevent installation of the overridden binaries, but if both
	// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
	// from PRODUCT_PACKAGES.
	Overrides []string
}

func (a *ApexSet) hasSanitizedSource(sanitizer string) bool {
	if sanitizer == "address" {
		return a.properties.Sanitized.Address.Set != nil
@@ -621,36 +668,55 @@ func (a *ApexSet) Overrides() []string {
// prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex.
func apexSetFactory() android.Module {
	module := &ApexSet{}
	module.AddProperties(&module.properties)
	module.AddProperties(&module.properties, &module.selectedApexProperties)

	srcsSupplier := func(ctx android.BaseModuleContext, _ android.Module) []string {
		return module.prebuiltSrcs(ctx)
	}

	android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "set")
	android.InitSingleSourcePrebuiltModule(module, &module.selectedApexProperties, "Selected_apex")
	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)

	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
		baseModuleName := module.BaseModuleName()

		apexExtractorModuleName := apexExtractorModuleName(baseModuleName)
		createApexExtractorModule(ctx, apexExtractorModuleName, &module.properties.ApexExtractorProperties)

		apexFileSource := ":" + apexExtractorModuleName

		// After passing the arch specific src properties to the creating the apex selector module
		module.selectedApexProperties.Selected_apex = proptools.StringPtr(apexFileSource)
	})

	return module
}

func createApexExtractorModule(ctx android.LoadHookContext, name string, apexExtractorProperties *ApexExtractorProperties) {
	props := struct {
		Name *string
	}{
		Name: proptools.StringPtr(name),
	}

	ctx.CreateModule(privateApexExtractorModuleFactory,
		&props,
		apexExtractorProperties,
	)
}

func apexExtractorModuleName(baseModuleName string) string {
	return baseModuleName + ".apex.extractor"
}

func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	a.installFilename = a.InstallFilename()
	if !strings.HasSuffix(a.installFilename, imageApexSuffix) {
		ctx.ModuleErrorf("filename should end in %s for apex_set", imageApexSuffix)
	}

	apexSet := a.prebuiltCommon.prebuilt.SingleSourcePath(ctx)
	inputApex := android.OptionalPathForModuleSrc(ctx, a.selectedApexProperties.Selected_apex).Path()
	a.outputApex = android.PathForModuleOut(ctx, a.installFilename)
	ctx.Build(pctx,
		android.BuildParams{
			Rule:        extractMatchingApex,
			Description: "Extract an apex from an apex set",
			Inputs:      android.Paths{apexSet},
	ctx.Build(pctx, android.BuildParams{
		Rule:   android.Cp,
		Input:  inputApex,
		Output: a.outputApex,
			Args: map[string]string{
				"abis":              strings.Join(java.SupportedAbis(ctx), ","),
				"allow-prereleased": strconv.FormatBool(proptools.Bool(a.properties.Prerelease)),
				"sdk-version":       ctx.Config().PlatformSdkVersion().String(),
			},
	})

	if a.prebuiltCommon.checkForceDisable(ctx) {