Loading android/module.go +7 −0 Original line number Diff line number Diff line Loading @@ -886,6 +886,13 @@ func (m *ModuleBase) SystemExtSpecific() bool { return Bool(m.commonProperties.System_ext_specific) } // RequiresStableAPIs returns true if the module will be installed to a partition that may // be updated separately from the system image. func (m *ModuleBase) RequiresStableAPIs(ctx BaseModuleContext) bool { return m.SocSpecific() || m.DeviceSpecific() || (m.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) } func (m *ModuleBase) PartitionTag(config DeviceConfig) string { partition := "system" if m.SocSpecific() { Loading java/app.go +32 −15 Original line number Diff line number Diff line Loading @@ -374,7 +374,10 @@ func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { // If the app builds against an Android SDK use the SDK variant of JNI dependencies // unless jni_uses_platform_apis is set. if (usesSDK && !Bool(a.appProperties.Jni_uses_platform_apis)) || // Don't require the SDK variant for apps that are shipped on vendor, etc., as they already // have stable APIs through the VNDK. if (usesSDK && !a.RequiresStableAPIs(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)) || Bool(a.appProperties.Jni_uses_sdk_apis) { variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"}) } Loading Loading @@ -705,7 +708,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { dexJarFile := a.dexBuildActions(ctx) jniLibs, certificateDeps := collectAppDeps(ctx, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis)) jniLibs, certificateDeps := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis)) jniJarFile := a.jniBuildActions(jniLibs, ctx) if ctx.Failed() { Loading Loading @@ -761,12 +764,25 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { a.buildAppDependencyInfo(ctx) } func collectAppDeps(ctx android.ModuleContext, shouldCollectRecursiveNativeDeps bool, type appDepsInterface interface { sdkVersion() sdkSpec minSdkVersion() sdkSpec RequiresStableAPIs(ctx android.BaseModuleContext) bool } func collectAppDeps(ctx android.ModuleContext, app appDepsInterface, shouldCollectRecursiveNativeDeps bool, checkNativeSdkVersion bool) ([]jniLib, []Certificate) { var jniLibs []jniLib var certificates []Certificate seenModulePaths := make(map[string]bool) if checkNativeSdkVersion { checkNativeSdkVersion = app.sdkVersion().specified() && app.sdkVersion().kind != sdkCorePlatform && !app.RequiresStableAPIs(ctx) } ctx.WalkDeps(func(module android.Module, parent android.Module) bool { otherName := ctx.OtherModuleName(module) tag := ctx.OtherModuleDependencyTag(module) Loading @@ -784,17 +800,10 @@ func collectAppDeps(ctx android.ModuleContext, shouldCollectRecursiveNativeDeps } seenModulePaths[path.String()] = true if checkNativeSdkVersion { if app, ok := ctx.Module().(interface{ sdkVersion() sdkSpec }); ok { if app.sdkVersion().specified() && app.sdkVersion().kind != sdkCorePlatform && dep.SdkVersion() == "" { ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not", if checkNativeSdkVersion && dep.SdkVersion() == "" { ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not", otherName) } } } if lib.Valid() { jniLibs = append(jniLibs, jniLib{ Loading Loading @@ -1379,7 +1388,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext ctx.ModuleErrorf("One and only one of certficate, presigned, and default_dev_cert properties must be set") } _, certificates := collectAppDeps(ctx, false, false) _, certificates := collectAppDeps(ctx, a, false, false) // TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK // TODO: LOCAL_PACKAGE_SPLITS Loading Loading @@ -1496,6 +1505,14 @@ func (a *AndroidAppImport) Privileged() bool { return Bool(a.properties.Privileged) } func (a *AndroidAppImport) sdkVersion() sdkSpec { return sdkSpecFrom("") } func (a *AndroidAppImport) minSdkVersion() sdkSpec { return sdkSpecFrom("") } func createVariantGroupType(variants []string, variantGroupName string) reflect.Type { props := reflect.TypeOf((*AndroidAppImportProperties)(nil)) Loading Loading @@ -1670,7 +1687,7 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC r.aapt.buildActions(ctx, r, aaptLinkFlags...) // Sign the built package _, certificates := collectAppDeps(ctx, false, false) _, certificates := collectAppDeps(ctx, r, false, false) certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx) signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk") SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil, nil) Loading java/app_test.go +33 −10 Original line number Diff line number Diff line Loading @@ -1232,25 +1232,44 @@ func TestJNISDK(t *testing.T) { platform_apis: true, jni_uses_sdk_apis: true, } cc_library { name: "libvendorjni", system_shared_libs: [], stl: "none", vendor: true, } android_test { name: "app_vendor", jni_libs: ["libvendorjni"], sdk_version: "current", vendor: true, } `) testCases := []struct { name string sdkJNI bool vendorJNI bool }{ {"app_platform", false}, {"app_sdk", true}, {"app_force_platform", false}, {"app_force_sdk", true}, {name: "app_platform"}, {name: "app_sdk", sdkJNI: true}, {name: "app_force_platform"}, {name: "app_force_sdk", sdkJNI: true}, {name: "app_vendor", vendorJNI: true}, } for _, test := range testCases { t.Run(test.name, func(t *testing.T) { app := ctx.ModuleForTests(test.name, "android_common") platformJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_shared"). Output("libjni.so").Output.String() sdkJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared"). Output("libjni.so").Output.String() vendorJNI := ctx.ModuleForTests("libvendorjni", "android_arm64_armv8-a_shared"). Output("libvendorjni.so").Output.String() for _, test := range testCases { t.Run(test.name, func(t *testing.T) { app := ctx.ModuleForTests(test.name, "android_common") jniLibZip := app.MaybeOutput("jnilibs.zip") if len(jniLibZip.Implicits) != 1 { Loading @@ -1262,6 +1281,10 @@ func TestJNISDK(t *testing.T) { if gotJNI != sdkJNI { t.Errorf("expected SDK JNI library %q, got %q", sdkJNI, gotJNI) } } else if test.vendorJNI { if gotJNI != vendorJNI { t.Errorf("expected platform JNI library %q, got %q", vendorJNI, gotJNI) } } else { if gotJNI != platformJNI { t.Errorf("expected platform JNI library %q, got %q", platformJNI, gotJNI) Loading java/java.go +1 −2 Original line number Diff line number Diff line Loading @@ -95,8 +95,7 @@ func (j *Module) CheckStableSdkVersion() error { } func (j *Module) checkSdkVersions(ctx android.ModuleContext) { if j.SocSpecific() || j.DeviceSpecific() || (j.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) { if j.RequiresStableAPIs(ctx) { if sc, ok := ctx.Module().(sdkContext); ok { if !sc.sdkVersion().specified() { ctx.PropertyErrorf("sdk_version", Loading Loading
android/module.go +7 −0 Original line number Diff line number Diff line Loading @@ -886,6 +886,13 @@ func (m *ModuleBase) SystemExtSpecific() bool { return Bool(m.commonProperties.System_ext_specific) } // RequiresStableAPIs returns true if the module will be installed to a partition that may // be updated separately from the system image. func (m *ModuleBase) RequiresStableAPIs(ctx BaseModuleContext) bool { return m.SocSpecific() || m.DeviceSpecific() || (m.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) } func (m *ModuleBase) PartitionTag(config DeviceConfig) string { partition := "system" if m.SocSpecific() { Loading
java/app.go +32 −15 Original line number Diff line number Diff line Loading @@ -374,7 +374,10 @@ func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { // If the app builds against an Android SDK use the SDK variant of JNI dependencies // unless jni_uses_platform_apis is set. if (usesSDK && !Bool(a.appProperties.Jni_uses_platform_apis)) || // Don't require the SDK variant for apps that are shipped on vendor, etc., as they already // have stable APIs through the VNDK. if (usesSDK && !a.RequiresStableAPIs(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)) || Bool(a.appProperties.Jni_uses_sdk_apis) { variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"}) } Loading Loading @@ -705,7 +708,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { dexJarFile := a.dexBuildActions(ctx) jniLibs, certificateDeps := collectAppDeps(ctx, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis)) jniLibs, certificateDeps := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis)) jniJarFile := a.jniBuildActions(jniLibs, ctx) if ctx.Failed() { Loading Loading @@ -761,12 +764,25 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { a.buildAppDependencyInfo(ctx) } func collectAppDeps(ctx android.ModuleContext, shouldCollectRecursiveNativeDeps bool, type appDepsInterface interface { sdkVersion() sdkSpec minSdkVersion() sdkSpec RequiresStableAPIs(ctx android.BaseModuleContext) bool } func collectAppDeps(ctx android.ModuleContext, app appDepsInterface, shouldCollectRecursiveNativeDeps bool, checkNativeSdkVersion bool) ([]jniLib, []Certificate) { var jniLibs []jniLib var certificates []Certificate seenModulePaths := make(map[string]bool) if checkNativeSdkVersion { checkNativeSdkVersion = app.sdkVersion().specified() && app.sdkVersion().kind != sdkCorePlatform && !app.RequiresStableAPIs(ctx) } ctx.WalkDeps(func(module android.Module, parent android.Module) bool { otherName := ctx.OtherModuleName(module) tag := ctx.OtherModuleDependencyTag(module) Loading @@ -784,17 +800,10 @@ func collectAppDeps(ctx android.ModuleContext, shouldCollectRecursiveNativeDeps } seenModulePaths[path.String()] = true if checkNativeSdkVersion { if app, ok := ctx.Module().(interface{ sdkVersion() sdkSpec }); ok { if app.sdkVersion().specified() && app.sdkVersion().kind != sdkCorePlatform && dep.SdkVersion() == "" { ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not", if checkNativeSdkVersion && dep.SdkVersion() == "" { ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not", otherName) } } } if lib.Valid() { jniLibs = append(jniLibs, jniLib{ Loading Loading @@ -1379,7 +1388,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext ctx.ModuleErrorf("One and only one of certficate, presigned, and default_dev_cert properties must be set") } _, certificates := collectAppDeps(ctx, false, false) _, certificates := collectAppDeps(ctx, a, false, false) // TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK // TODO: LOCAL_PACKAGE_SPLITS Loading Loading @@ -1496,6 +1505,14 @@ func (a *AndroidAppImport) Privileged() bool { return Bool(a.properties.Privileged) } func (a *AndroidAppImport) sdkVersion() sdkSpec { return sdkSpecFrom("") } func (a *AndroidAppImport) minSdkVersion() sdkSpec { return sdkSpecFrom("") } func createVariantGroupType(variants []string, variantGroupName string) reflect.Type { props := reflect.TypeOf((*AndroidAppImportProperties)(nil)) Loading Loading @@ -1670,7 +1687,7 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC r.aapt.buildActions(ctx, r, aaptLinkFlags...) // Sign the built package _, certificates := collectAppDeps(ctx, false, false) _, certificates := collectAppDeps(ctx, r, false, false) certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx) signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk") SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil, nil) Loading
java/app_test.go +33 −10 Original line number Diff line number Diff line Loading @@ -1232,25 +1232,44 @@ func TestJNISDK(t *testing.T) { platform_apis: true, jni_uses_sdk_apis: true, } cc_library { name: "libvendorjni", system_shared_libs: [], stl: "none", vendor: true, } android_test { name: "app_vendor", jni_libs: ["libvendorjni"], sdk_version: "current", vendor: true, } `) testCases := []struct { name string sdkJNI bool vendorJNI bool }{ {"app_platform", false}, {"app_sdk", true}, {"app_force_platform", false}, {"app_force_sdk", true}, {name: "app_platform"}, {name: "app_sdk", sdkJNI: true}, {name: "app_force_platform"}, {name: "app_force_sdk", sdkJNI: true}, {name: "app_vendor", vendorJNI: true}, } for _, test := range testCases { t.Run(test.name, func(t *testing.T) { app := ctx.ModuleForTests(test.name, "android_common") platformJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_shared"). Output("libjni.so").Output.String() sdkJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared"). Output("libjni.so").Output.String() vendorJNI := ctx.ModuleForTests("libvendorjni", "android_arm64_armv8-a_shared"). Output("libvendorjni.so").Output.String() for _, test := range testCases { t.Run(test.name, func(t *testing.T) { app := ctx.ModuleForTests(test.name, "android_common") jniLibZip := app.MaybeOutput("jnilibs.zip") if len(jniLibZip.Implicits) != 1 { Loading @@ -1262,6 +1281,10 @@ func TestJNISDK(t *testing.T) { if gotJNI != sdkJNI { t.Errorf("expected SDK JNI library %q, got %q", sdkJNI, gotJNI) } } else if test.vendorJNI { if gotJNI != vendorJNI { t.Errorf("expected platform JNI library %q, got %q", vendorJNI, gotJNI) } } else { if gotJNI != platformJNI { t.Errorf("expected platform JNI library %q, got %q", platformJNI, gotJNI) Loading
java/java.go +1 −2 Original line number Diff line number Diff line Loading @@ -95,8 +95,7 @@ func (j *Module) CheckStableSdkVersion() error { } func (j *Module) checkSdkVersions(ctx android.ModuleContext) { if j.SocSpecific() || j.DeviceSpecific() || (j.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) { if j.RequiresStableAPIs(ctx) { if sc, ok := ctx.Module().(sdkContext); ok { if !sc.sdkVersion().specified() { ctx.PropertyErrorf("sdk_version", Loading