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

Commit 84b2589e authored by Jihoon Kang's avatar Jihoon Kang
Browse files

Add aconfig flag support for android_app

This change adds an overrideable property flags_packages to android_app,
which is used to list the aconfig_declarations module names that the app
depends on. The build action of android_app is modified to pass all
flags text file provided by the aconfig_declarations to aapt2 link as
--feature-flags arguments.

Test: m nothing --no-skip-soong-tests
Bug: 306024510
Change-Id: I4924f88b9954950cc1936a472cd7ac70f41add5d
parent cca3e0c4
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -202,7 +202,8 @@ var mergeAssetsRule = pctx.AndroidStaticRule("mergeAssets",
func aapt2Link(ctx android.ModuleContext,
	packageRes, genJar, proguardOptions, rTxt android.WritablePath,
	flags []string, deps android.Paths,
	compiledRes, compiledOverlay, assetPackages android.Paths, splitPackages android.WritablePaths) {
	compiledRes, compiledOverlay, assetPackages android.Paths, splitPackages android.WritablePaths,
	featureFlagsPaths android.Paths) {

	var inFlags []string

@@ -255,6 +256,11 @@ func aapt2Link(ctx android.ModuleContext,
		})
	}

	for _, featureFlagsPath := range featureFlagsPaths {
		deps = append(deps, featureFlagsPath)
		inFlags = append(inFlags, "--feature-flags", "@"+featureFlagsPath.String())
	}

	// Note the absence of splitPackages. The caller is supposed to compose and provide --split flag
	// values via the flags parameter when it wants to split outputs.
	// TODO(b/174509108): Perhaps we can process it in this func while keeping the code reasonably
+4 −2
Original line number Diff line number Diff line
@@ -349,6 +349,7 @@ type aaptBuildActionOptions struct {
	excludedLibs                   []string
	enforceDefaultTargetSdkVersion bool
	extraLinkFlags                 []string
	aconfigTextFiles               android.Paths
}

func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptions) {
@@ -529,7 +530,8 @@ func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptio
		transitiveAssets = android.ReverseSliceInPlace(staticDeps.assets())
	}
	aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt,
		linkFlags, linkDeps, compiledRes, compiledOverlay, transitiveAssets, splitPackages)
		linkFlags, linkDeps, compiledRes, compiledOverlay, transitiveAssets, splitPackages,
		opts.aconfigTextFiles)
	// Extract assets from the resource package output so that they can be used later in aapt2link
	// for modules that depend on this one.
	if android.PrefixInList(linkFlags, "-A ") {
@@ -1193,7 +1195,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {

	transitiveAssets := android.ReverseSliceInPlace(staticDeps.assets())
	aapt2Link(ctx, a.exportPackage, nil, proguardOptionsFile, a.rTxt,
		linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil)
		linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil, nil)

	a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar")
	resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true)
+28 −5
Original line number Diff line number Diff line
@@ -22,7 +22,9 @@ import (
	"path/filepath"
	"strings"

	"android/soong/aconfig"
	"android/soong/testing"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"

@@ -170,6 +172,9 @@ type overridableAppProperties struct {
	// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
	// from PRODUCT_PACKAGES.
	Overrides []string

	// Names of aconfig_declarations modules that specify aconfig flags that the app depends on.
	Flags_packages []string
}

type AndroidApp struct {
@@ -316,6 +321,10 @@ func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutato
				`must be names of android_app_certificate modules in the form ":module"`)
		}
	}

	for _, aconfig_declaration := range a.overridableAppProperties.Flags_packages {
		ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
	}
}

func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -500,13 +509,27 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
	if a.Updatable() {
		a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion
	}

	var aconfigTextFilePaths android.Paths
	ctx.VisitDirectDepsWithTag(aconfigDeclarationTag, func(dep android.Module) {
		if provider, ok := ctx.OtherModuleProvider(dep, aconfig.DeclarationsProviderKey).(aconfig.DeclarationsProviderData); ok {
			aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
		} else {
			ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
				"flags_packages property, but %s is not aconfig_declarations module type",
				dep.Name(),
			)
		}
	})

	a.aapt.buildActions(ctx,
		aaptBuildActionOptions{
			android.SdkContext(a),
			a.classLoaderContexts,
			a.usesLibraryProperties.Exclude_uses_libs,
			a.enforceDefaultTargetSdkVersion(),
			aaptLinkFlags,
			sdkContext:                     android.SdkContext(a),
			classLoaderContexts:            a.classLoaderContexts,
			excludedLibs:                   a.usesLibraryProperties.Exclude_uses_libs,
			enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
			extraLinkFlags:                 aaptLinkFlags,
			aconfigTextFiles:               aconfigTextFilePaths,
		},
	)

+45 −0
Original line number Diff line number Diff line
@@ -4333,3 +4333,48 @@ func TestApexGlobalMinSdkVersionOverride(t *testing.T) {
	)

}

func TestAppFlagsPackages(t *testing.T) {
	ctx := testApp(t, `
		android_app {
			name: "foo",
			srcs: ["a.java"],
			sdk_version: "current",
			flags_packages: [
				"bar",
				"baz",
			],
		}
		aconfig_declarations {
			name: "bar",
			package: "com.example.package",
			srcs: [
				"bar.aconfig",
			],
		}
		aconfig_declarations {
			name: "baz",
			package: "com.example.package",
			srcs: [
				"baz.aconfig",
			],
		}
	`)

	foo := ctx.ModuleForTests("foo", "android_common")

	// android_app module depends on aconfig_declarations listed in flags_packages
	android.AssertBoolEquals(t, "foo expected to depend on bar", true,
		CheckModuleHasDependency(t, ctx, "foo", "android_common", "bar"))

	android.AssertBoolEquals(t, "foo expected to depend on baz", true,
		CheckModuleHasDependency(t, ctx, "foo", "android_common", "baz"))

	aapt2LinkRule := foo.Rule("android/soong/java.aapt2Link")
	linkInFlags := aapt2LinkRule.Args["inFlags"]
	android.AssertStringDoesContain(t,
		"aapt2 link command expected to pass feature flags arguments",
		linkInFlags,
		"--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
	)
}
+1 −0
Original line number Diff line number Diff line
@@ -409,6 +409,7 @@ var (
	syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
	javaApiContributionTag  = dependencyTag{name: "java-api-contribution"}
	depApiSrcsTag           = dependencyTag{name: "dep-api-srcs"}
	aconfigDeclarationTag   = dependencyTag{name: "aconfig-declaration"}
	jniInstallTag           = installDependencyTag{name: "jni install"}
	binaryInstallTag        = installDependencyTag{name: "binary install"}
	usesLibReqTag           = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false)
Loading