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

Commit 7c140d82 authored by Ulya Trafimovich's avatar Ulya Trafimovich
Browse files

Add "updatable" property to ApexModule interface.

For a given variant of a module that implements ApexModule interface,
the "updatable" property tests if this variant comes from an updatable
apex. For platform variants it is always false.

Test: lunch aosp_walleye-userdebug && m nothing
Bug: 138994281
Change-Id: I2d4c54fb397e29dc9b3203be7fb17be4536529f7
parent acc5448f
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ type ApexInfo struct {
	ApexName string

	MinSdkVersion int
	Updatable     bool
}

// Extracted from ApexModule to make it easier to define custom subsets of the
@@ -104,6 +105,9 @@ type ApexModule interface {
	// For example, with maxSdkVersion is 10 and versionList is [9,11]
	// it returns 9 as string
	ChooseSdkVersion(versionList []string, maxSdkVersion int) (string, error)

	// Tests if the module comes from an updatable APEX.
	Updatable() bool
}

type ApexProperties struct {
@@ -229,6 +233,10 @@ func (m *ApexModuleBase) checkApexAvailableProperty(mctx BaseModuleContext) {
	}
}

func (m *ApexModuleBase) Updatable() bool {
	return m.ApexProperties.Info.Updatable
}

type byApexName []ApexInfo

func (a byApexName) Len() int           { return len(a) }
+1 −0
Original line number Diff line number Diff line
@@ -845,6 +845,7 @@ func apexDepsMutator(mctx android.TopDownMutatorContext) {
		apexBundles = []android.ApexInfo{{
			ApexName:      mctx.ModuleName(),
			MinSdkVersion: a.minSdkVersion(mctx),
			Updatable:     proptools.Bool(a.properties.Updatable),
		}}
		directDep = true
	} else if am, ok := mctx.Module().(android.ApexModule); ok {
+42 −1
Original line number Diff line number Diff line
@@ -4276,6 +4276,13 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg, bp string, transformDe
				"system/sepolicy/apex/some-updatable-apex-file_contexts",
			],
		}

		filegroup {
			name: "some-non-updatable-apex-file_contexts",
			srcs: [
				"system/sepolicy/apex/some-non-updatable-apex-file_contexts",
			],
		}
	`
	bp += cc.GatherRequiredDepsForTest(android.Android)
	bp += java.GatherRequiredDepsForTest()
@@ -4288,6 +4295,7 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg, bp string, transformDe
		"apex_manifest.json":                 nil,
		"AndroidManifest.xml":                nil,
		"system/sepolicy/apex/some-updatable-apex-file_contexts":       nil,
		"system/sepolicy/apex/some-non-updatable-apex-file_contexts":   nil,
		"system/sepolicy/apex/com.android.art.something-file_contexts": nil,
		"framework/aidl/a.aidl": nil,
	}
@@ -4341,6 +4349,14 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
			],
		}

		java_library {
			name: "some-non-updatable-apex-lib",
			srcs: ["a.java"],
			apex_available: [
				"some-non-updatable-apex",
			],
		}

		java_library {
			name: "some-platform-lib",
			srcs: ["a.java"],
@@ -4360,16 +4376,28 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
			name: "some-updatable-apex",
			key: "some-updatable-apex.key",
			java_libs: ["some-updatable-apex-lib"],
			updatable: true,
		}

		apex {
			name: "some-non-updatable-apex",
			key: "some-non-updatable-apex.key",
			java_libs: ["some-non-updatable-apex-lib"],
		}

		apex_key {
			name: "some-updatable-apex.key",
		}

		apex_key {
			name: "some-non-updatable-apex.key",
		}

		apex {
			name: "com.android.art.something",
			key: "com.android.art.something.key",
			java_libs: ["some-art-lib"],
			updatable: true,
		}

		apex_key {
@@ -4400,6 +4428,13 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
	}
	testNoUpdatableJarsInBootImage(t, error, bp, transform)

	// non-updatable jar from some other apex in the ART boot image => error
	error = "module 'some-non-updatable-apex-lib' is not allowed in the ART boot image"
	transform = func(config *dexpreopt.GlobalConfig) {
		config.ArtApexJars = []string{"some-non-updatable-apex-lib"}
	}
	testNoUpdatableJarsInBootImage(t, error, bp, transform)

	// updatable jar from some other apex in the framework boot image => error
	error = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the framework boot image"
	transform = func(config *dexpreopt.GlobalConfig) {
@@ -4407,6 +4442,12 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
	}
	testNoUpdatableJarsInBootImage(t, error, bp, transform)

	// non-updatable jar from some other apex in the framework boot image => ok
	transform = func(config *dexpreopt.GlobalConfig) {
		config.BootJars = []string{"some-non-updatable-apex-lib"}
	}
	testNoUpdatableJarsInBootImage(t, "", bp, transform)

	// nonexistent jar in the ART boot image => error
	error = "failed to find a dex jar path for module 'nonexistent'"
	transform = func(config *dexpreopt.GlobalConfig) {
@@ -4422,7 +4463,7 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
	testNoUpdatableJarsInBootImage(t, error, bp, transform)

	// platform jar in the ART boot image => error
	error = "module 'some-platform-lib' is part of the platform and not allowed in the ART boot image"
	error = "module 'some-platform-lib' is not allowed in the ART boot image"
	transform = func(config *dexpreopt.GlobalConfig) {
		config.ArtApexJars = []string{"some-platform-lib"}
	}
+12 −11
Original line number Diff line number Diff line
@@ -268,27 +268,28 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul

	// Check that this module satisfies constraints for a particular boot image.
	apex, isApexModule := module.(android.ApexModule)
	fromUpdatableApex := isApexModule && apex.Updatable()
	if image.name == artBootImageName {
		if isApexModule && strings.HasPrefix(apex.ApexName(), "com.android.art.") {
			// ok, found the jar in the ART apex
		} else if isApexModule && !apex.IsForPlatform() {
			// this jar is part of an updatable apex other than ART, fail immediately
			ctx.Errorf("module '%s' from updatable apex '%s' is not allowed in the ART boot image", name, apex.ApexName())
			// ok: found the jar in the ART apex
		} else if isApexModule && apex.IsForPlatform() && Bool(module.(*Library).deviceProperties.Hostdex) {
			// this is a special "hostdex" variant, skip it and resume search
			// exception (skip and continue): special "hostdex" platform variant
			return -1, nil
		} else if name == "jacocoagent" && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
			// this is Jacoco platform variant for a coverage build, skip it and resume search
			// exception (skip and continue): Jacoco platform variant for a coverage build
			return -1, nil
		} else if fromUpdatableApex {
			// error: this jar is part of an updatable apex other than ART
			ctx.Errorf("module '%s' from updatable apex '%s' is not allowed in the ART boot image", name, apex.ApexName())
		} else {
			// this (installable) jar is part of the platform, fail immediately
			ctx.Errorf("module '%s' is part of the platform and not allowed in the ART boot image", name)
			// error: this jar is part of the platform or a non-updatable apex
			ctx.Errorf("module '%s' is not allowed in the ART boot image", name)
		}
	} else if image.name == frameworkBootImageName {
		if !isApexModule || apex.IsForPlatform() {
			// ok, this jar is part of the platform
		if !fromUpdatableApex {
			// ok: this jar is part of the platform or a non-updatable apex
		} else {
			// this jar is part of an updatable apex, fail immediately
			// error: this jar is part of an updatable apex
			ctx.Errorf("module '%s' from updatable apex '%s' is not allowed in the framework boot image", name, apex.ApexName())
		}
	} else {