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

Commit 9d6ea77c authored by satayev's avatar satayev Committed by Gerrit Code Review
Browse files

Merge "Ensure APEX's Java deps use stable SDKs."

parents 817133ee 8cf899af
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -1885,6 +1885,8 @@ func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
		if String(a.properties.Min_sdk_version) == "" {
			ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
		}

		a.checkJavaStableSdkVersion(ctx)
	}
}

@@ -1954,7 +1956,6 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {

	a.checkApexAvailability(ctx)
	a.checkUpdatable(ctx)

	a.collectDepsInfo(ctx)

	handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
@@ -2274,6 +2275,23 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	a.buildApexDependencyInfo(ctx)
}

// Enforce that Java deps of the apex are using stable SDKs to compile
func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
	// Visit direct deps only. As long as we guarantee top-level deps are using
	// stable SDKs, java's checkLinkType guarantees correct usage for transitive deps
	ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
		tag := ctx.OtherModuleDependencyTag(module)
		switch tag {
		case javaLibTag, androidAppTag:
			if m, ok := module.(interface{ CheckStableSdkVersion() error }); ok {
				if err := m.CheckStableSdkVersion(); err != nil {
					ctx.ModuleErrorf("cannot depend on \"%v\": %v", ctx.OtherModuleName(module), err)
				}
			}
		}
	})
}

func whitelistedApexAvailable(apex, moduleName string) bool {
	key := apex
	moduleName = normalizeModuleName(moduleName)
+119 −0
Original line number Diff line number Diff line
@@ -1411,6 +1411,122 @@ func TestInvalidMinSdkVersion(t *testing.T) {
	`)
}

func TestJavaStableSdkVersion(t *testing.T) {
	testCases := []struct {
		name          string
		expectedError string
		bp            string
	}{
		{
			name: "Non-updatable apex with non-stable dep",
			bp: `
				apex {
					name: "myapex",
					java_libs: ["myjar"],
					key: "myapex.key",
				}
				apex_key {
					name: "myapex.key",
					public_key: "testkey.avbpubkey",
					private_key: "testkey.pem",
				}
				java_library {
					name: "myjar",
					srcs: ["foo/bar/MyClass.java"],
					sdk_version: "core_platform",
					apex_available: ["myapex"],
				}
			`,
		},
		{
			name: "Updatable apex with stable dep",
			bp: `
				apex {
					name: "myapex",
					java_libs: ["myjar"],
					key: "myapex.key",
					updatable: true,
					min_sdk_version: "29",
				}
				apex_key {
					name: "myapex.key",
					public_key: "testkey.avbpubkey",
					private_key: "testkey.pem",
				}
				java_library {
					name: "myjar",
					srcs: ["foo/bar/MyClass.java"],
					sdk_version: "current",
					apex_available: ["myapex"],
				}
			`,
		},
		{
			name:          "Updatable apex with non-stable dep",
			expectedError: "cannot depend on \"myjar\"",
			bp: `
				apex {
					name: "myapex",
					java_libs: ["myjar"],
					key: "myapex.key",
					updatable: true,
				}
				apex_key {
					name: "myapex.key",
					public_key: "testkey.avbpubkey",
					private_key: "testkey.pem",
				}
				java_library {
					name: "myjar",
					srcs: ["foo/bar/MyClass.java"],
					sdk_version: "core_platform",
					apex_available: ["myapex"],
				}
			`,
		},
		{
			name:          "Updatable apex with non-stable transitive dep",
			expectedError: "compiles against Android API, but dependency \"transitive-jar\" is compiling against non-public Android API.",
			bp: `
				apex {
					name: "myapex",
					java_libs: ["myjar"],
					key: "myapex.key",
					updatable: true,
				}
				apex_key {
					name: "myapex.key",
					public_key: "testkey.avbpubkey",
					private_key: "testkey.pem",
				}
				java_library {
					name: "myjar",
					srcs: ["foo/bar/MyClass.java"],
					sdk_version: "current",
					apex_available: ["myapex"],
					static_libs: ["transitive-jar"],
				}
				java_library {
					name: "transitive-jar",
					srcs: ["foo/bar/MyClass.java"],
					sdk_version: "core_platform",
					apex_available: ["myapex"],
				}
			`,
		},
	}

	for _, test := range testCases {
		t.Run(test.name, func(t *testing.T) {
			if test.expectedError == "" {
				testApex(t, test.bp)
			} else {
				testApexError(t, test.expectedError, test.bp)
			}
		})
	}
}

func TestFilesInSubDir(t *testing.T) {
	ctx, _ := testApex(t, `
		apex {
@@ -4458,6 +4574,7 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
		java_library {
			name: "some-updatable-apex-lib",
			srcs: ["a.java"],
			sdk_version: "current",
			apex_available: [
				"some-updatable-apex",
			],
@@ -4474,12 +4591,14 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
		java_library {
			name: "some-platform-lib",
			srcs: ["a.java"],
			sdk_version: "current",
			installable: true,
		}

		java_library {
			name: "some-art-lib",
			srcs: ["a.java"],
			sdk_version: "current",
			apex_available: [
				"com.android.art.something",
			],
+8 −0
Original line number Diff line number Diff line
@@ -86,6 +86,14 @@ func RegisterJavaBuildComponents(ctx android.RegistrationContext) {
	ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
}

func (j *Module) CheckStableSdkVersion() error {
	sdkVersion := j.sdkVersion()
	if sdkVersion.stable() {
		return nil
	}
	return fmt.Errorf("non stable SDK %v", sdkVersion)
}

func (j *Module) checkSdkVersions(ctx android.ModuleContext) {
	if j.SocSpecific() || j.DeviceSpecific() ||
		(j.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
+4 −1
Original line number Diff line number Diff line
@@ -169,9 +169,12 @@ func (s sdkSpec) stable() bool {
		return false
	}
	switch s.kind {
	case sdkNone:
		// there is nothing to manage and version in this case; de facto stable API.
		return true
	case sdkCore, sdkPublic, sdkSystem, sdkModule, sdkSystemServer:
		return true
	case sdkNone, sdkCorePlatform, sdkTest, sdkPrivate:
	case sdkCorePlatform, sdkTest, sdkPrivate:
		return false
	default:
		panic(fmt.Errorf("unknown sdkKind=%v", s.kind))