diff --git a/java/app.go b/java/app.go index a679e8823..674e5ece0 100644 --- a/java/app.go +++ b/java/app.go @@ -191,9 +191,12 @@ func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutato } } +func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { + a.generateAndroidBuildActions(ctx) +} + func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { - a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx) - a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex) + a.checkPlatformAPI(ctx) a.generateAndroidBuildActions(ctx) } @@ -422,6 +425,9 @@ func processMainCert(m android.ModuleBase, certPropValue string, certificates [] func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { var apkDeps android.Paths + a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx) + a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex) + // Check if the install APK name needs to be overridden. a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(a.Name()) @@ -584,8 +590,6 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName) } } - a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx) - a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex) a.generateAndroidBuildActions(ctx) a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites) diff --git a/java/app_test.go b/java/app_test.go index 32de019f1..f6a307e97 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -72,6 +72,7 @@ func TestApp(t *testing.T) { ctx := testApp(t, moduleType+` { name: "foo", srcs: ["a.java"], + sdk_version: "current" } `) @@ -117,6 +118,7 @@ func TestAppSplits(t *testing.T) { name: "foo", srcs: ["a.java"], package_splits: ["v4", "v7,hdpi"], + sdk_version: "current" }`) foo := ctx.ModuleForTests("foo", "android_common") @@ -139,6 +141,40 @@ func TestAppSplits(t *testing.T) { } } +func TestPlatformAPIs(t *testing.T) { + testJava(t, ` + android_app { + name: "foo", + srcs: ["a.java"], + platform_apis: true, + } + `) + + testJava(t, ` + android_app { + name: "foo", + srcs: ["a.java"], + sdk_version: "current", + } + `) + + testJavaError(t, "platform_apis must be true when sdk_version is empty.", ` + android_app { + name: "bar", + srcs: ["b.java"], + } + `) + + testJavaError(t, "platform_apis must be false when sdk_version is not empty.", ` + android_app { + name: "bar", + srcs: ["b.java"], + sdk_version: "system_current", + platform_apis: true, + } + `) +} + func TestResourceDirs(t *testing.T) { testCases := []struct { name string @@ -169,6 +205,7 @@ func TestResourceDirs(t *testing.T) { bp := ` android_app { name: "foo", + sdk_version: "current", %s } ` @@ -349,12 +386,14 @@ func TestAndroidResources(t *testing.T) { bp := ` android_app { name: "foo", + sdk_version: "current", resource_dirs: ["foo/res"], static_libs: ["lib", "lib3"], } android_app { name: "bar", + sdk_version: "current", resource_dirs: ["bar/res"], } @@ -461,6 +500,7 @@ func TestAppSdkVersion(t *testing.T) { platformSdkCodename string platformSdkFinal bool expectedMinSdkVersion string + platformApis bool }{ { name: "current final SDK", @@ -481,6 +521,7 @@ func TestAppSdkVersion(t *testing.T) { { name: "default final SDK", sdkVersion: "", + platformApis: true, platformSdkInt: 27, platformSdkCodename: "REL", platformSdkFinal: true, @@ -489,6 +530,7 @@ func TestAppSdkVersion(t *testing.T) { { name: "default non-final SDK", sdkVersion: "", + platformApis: true, platformSdkInt: 27, platformSdkCodename: "OMR1", platformSdkFinal: false, @@ -504,11 +546,16 @@ func TestAppSdkVersion(t *testing.T) { for _, moduleType := range []string{"android_app", "android_library"} { for _, test := range testCases { t.Run(moduleType+" "+test.name, func(t *testing.T) { + platformApiProp := "" + if test.platformApis { + platformApiProp = "platform_apis: true," + } bp := fmt.Sprintf(`%s { name: "foo", srcs: ["a.java"], sdk_version: "%s", - }`, moduleType, test.sdkVersion) + %s + }`, moduleType, test.sdkVersion, platformApiProp) config := testConfig(nil) config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt @@ -630,18 +677,21 @@ func TestJNIPackaging(t *testing.T) { android_app { name: "app", jni_libs: ["libjni"], + sdk_version: "current", } android_app { name: "app_noembed", jni_libs: ["libjni"], use_embedded_native_libs: false, + sdk_version: "current", } android_app { name: "app_embed", jni_libs: ["libjni"], use_embedded_native_libs: true, + sdk_version: "current", } android_test { @@ -715,6 +765,7 @@ func TestCertificates(t *testing.T) { android_app { name: "foo", srcs: ["a.java"], + sdk_version: "current", } `, certificateOverride: "", @@ -726,7 +777,8 @@ func TestCertificates(t *testing.T) { android_app { name: "foo", srcs: ["a.java"], - certificate: ":new_certificate" + certificate: ":new_certificate", + sdk_version: "current", } android_app_certificate { @@ -743,7 +795,8 @@ func TestCertificates(t *testing.T) { android_app { name: "foo", srcs: ["a.java"], - certificate: "expiredkey" + certificate: "expiredkey", + sdk_version: "current", } `, certificateOverride: "", @@ -755,7 +808,8 @@ func TestCertificates(t *testing.T) { android_app { name: "foo", srcs: ["a.java"], - certificate: "expiredkey" + certificate: "expiredkey", + sdk_version: "current", } android_app_certificate { @@ -801,6 +855,7 @@ func TestPackageNameOverride(t *testing.T) { android_app { name: "foo", srcs: ["a.java"], + sdk_version: "current", } `, packageNameOverride: "", @@ -815,6 +870,7 @@ func TestPackageNameOverride(t *testing.T) { android_app { name: "foo", srcs: ["a.java"], + sdk_version: "current", } `, packageNameOverride: "foo:bar", @@ -856,11 +912,13 @@ func TestInstrumentationTargetOverridden(t *testing.T) { android_app { name: "foo", srcs: ["a.java"], + sdk_version: "current", } android_test { name: "bar", instrumentation_for: "foo", + sdk_version: "current", } ` config := testConfig(nil) @@ -885,6 +943,7 @@ func TestOverrideAndroidApp(t *testing.T) { srcs: ["a.java"], certificate: "expiredkey", overrides: ["qux"], + sdk_version: "current", } override_android_app { @@ -984,6 +1043,7 @@ func TestOverrideAndroidAppDependency(t *testing.T) { android_app { name: "foo", srcs: ["a.java"], + sdk_version: "current", } override_android_app { @@ -1253,18 +1313,21 @@ func TestUsesLibraries(t *testing.T) { name: "foo", srcs: ["a.java"], api_packages: ["foo"], + sdk_version: "current", } java_sdk_library { name: "bar", srcs: ["a.java"], api_packages: ["bar"], + sdk_version: "current", } android_app { name: "app", srcs: ["a.java"], uses_libs: ["foo"], + sdk_version: "current", optional_uses_libs: [ "bar", "baz", @@ -1339,6 +1402,7 @@ func TestCodelessApp(t *testing.T) { android_app { name: "foo", srcs: ["a.java"], + sdk_version: "current", } `, noCode: false, @@ -1348,6 +1412,7 @@ func TestCodelessApp(t *testing.T) { bp: ` android_app { name: "foo", + sdk_version: "current", } `, noCode: true, @@ -1358,11 +1423,13 @@ func TestCodelessApp(t *testing.T) { android_app { name: "foo", static_libs: ["lib"], + sdk_version: "current", } java_library { name: "lib", srcs: ["a.java"], + sdk_version: "current", } `, noCode: false, @@ -1373,10 +1440,12 @@ func TestCodelessApp(t *testing.T) { android_app { name: "foo", static_libs: ["lib"], + sdk_version: "current", } java_library { name: "lib", + sdk_version: "current", } `, // TODO(jungjw): this should probably be true @@ -1406,6 +1475,7 @@ func TestEmbedNotice(t *testing.T) { jni_libs: ["libjni"], notice: "APP_NOTICE", embed_notices: true, + sdk_version: "current", } // No embed_notice flag @@ -1414,6 +1484,7 @@ func TestEmbedNotice(t *testing.T) { srcs: ["a.java"], jni_libs: ["libjni"], notice: "APP_NOTICE", + sdk_version: "current", } // No NOTICE files @@ -1421,6 +1492,7 @@ func TestEmbedNotice(t *testing.T) { name: "baz", srcs: ["a.java"], embed_notices: true, + sdk_version: "current", } cc_library { @@ -1435,6 +1507,7 @@ func TestEmbedNotice(t *testing.T) { srcs: [ ":gen", ], + sdk_version: "current", } genrule { @@ -1510,6 +1583,7 @@ func TestUncompressDex(t *testing.T) { android_app { name: "foo", srcs: ["a.java"], + sdk_version: "current", } `, uncompressedPlatform: true, @@ -1522,6 +1596,7 @@ func TestUncompressDex(t *testing.T) { name: "foo", use_embedded_dex: true, srcs: ["a.java"], + sdk_version: "current", } `, uncompressedPlatform: true, @@ -1534,6 +1609,7 @@ func TestUncompressDex(t *testing.T) { name: "foo", privileged: true, srcs: ["a.java"], + sdk_version: "current", } `, uncompressedPlatform: true, diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go index 22b7bb9d5..5550a4c17 100644 --- a/java/dexpreopt_test.go +++ b/java/dexpreopt_test.go @@ -30,6 +30,7 @@ func TestDexpreoptEnabled(t *testing.T) { android_app { name: "foo", srcs: ["a.java"], + sdk_version: "current", }`, enabled: true, }, @@ -57,6 +58,7 @@ func TestDexpreoptEnabled(t *testing.T) { bp: ` android_app { name: "foo", + sdk_version: "current", }`, enabled: false, }, @@ -66,11 +68,13 @@ func TestDexpreoptEnabled(t *testing.T) { android_app { name: "foo", static_libs: ["lib"], + sdk_version: "current", } java_library { name: "lib", srcs: ["a.java"], + sdk_version: "current", }`, enabled: true, }, diff --git a/java/java.go b/java/java.go index fb2ddf917..fea38b51f 100644 --- a/java/java.go +++ b/java/java.go @@ -53,6 +53,20 @@ func init() { android.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory) } +func (j *Module) checkPlatformAPI(ctx android.ModuleContext) { + if sc, ok := ctx.Module().(sdkContext); ok { + usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis) + if usePlatformAPI != (sc.sdkVersion() == "") { + if usePlatformAPI { + ctx.PropertyErrorf("platform_apis", "platform_apis must be false when sdk_version is not empty.") + } else { + ctx.PropertyErrorf("platform_apis", "platform_apis must be true when sdk_version is empty.") + } + } + + } +} + // TODO: // Autogenerated files: // Renderscript @@ -179,8 +193,8 @@ type CompilerDeviceProperties struct { // list of module-specific flags that will be used for dex compiles Dxflags []string `android:"arch_variant"` - // if not blank, set to the version of the sdk to compile against. Defaults to compiling against the current - // sdk if platform_apis is not set. + // if not blank, set to the version of the sdk to compile against. + // Defaults to compiling against the current platform. Sdk_version *string // if not blank, set the minimum version of the sdk that the compiled artifacts will run against. @@ -191,7 +205,8 @@ type CompilerDeviceProperties struct { // Defaults to sdk_version if not set. Target_sdk_version *string - // if true, compile against the platform APIs instead of an SDK. + // It must be true only if sdk_version is empty. + // This field works in only android_app, otherwise nothing happens. Platform_apis *bool Aidl struct { diff --git a/java/java_test.go b/java/java_test.go index d3d5c2459..17f3a218a 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -222,6 +222,29 @@ func run(t *testing.T, ctx *android.TestContext, config android.Config) { android.FailIfErrored(t, errs) } +func testJavaError(t *testing.T, pattern string, bp string) { + t.Helper() + config := testConfig(nil) + ctx := testContext(bp, nil) + + pathCtx := android.PathContextForTesting(config, nil) + setDexpreoptTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx)) + + ctx.Register() + _, errs := ctx.ParseBlueprintsFiles("Android.bp") + if len(errs) > 0 { + android.FailIfNoMatchingErrors(t, pattern, errs) + return + } + _, errs = ctx.PrepareBuildActions(config) + if len(errs) > 0 { + android.FailIfNoMatchingErrors(t, pattern, errs) + return + } + + t.Fatalf("missing expected error %q (0 errors are returned)", pattern) +} + func testJava(t *testing.T, bp string) (*android.TestContext, android.Config) { t.Helper() config := testConfig(nil)