diff options
Diffstat (limited to 'java')
| -rw-r--r-- | java/androidmk_test.go | 11 | ||||
| -rwxr-xr-x | java/app.go | 58 | ||||
| -rw-r--r-- | java/app_test.go | 14 | ||||
| -rw-r--r-- | java/hiddenapi_singleton.go | 2 | ||||
| -rw-r--r-- | java/hiddenapi_singleton_test.go | 194 | ||||
| -rw-r--r-- | java/java.go | 231 | ||||
| -rw-r--r-- | java/java_test.go | 317 | ||||
| -rw-r--r-- | java/legacy_core_platform_api_usage.go | 1 | ||||
| -rw-r--r-- | java/platform_compat_config.go | 14 | ||||
| -rw-r--r-- | java/proto.go | 2 | ||||
| -rw-r--r-- | java/sdk_library.go | 2 |
11 files changed, 451 insertions, 395 deletions
diff --git a/java/androidmk_test.go b/java/androidmk_test.go index e758a9247..347795639 100644 --- a/java/androidmk_test.go +++ b/java/androidmk_test.go @@ -135,7 +135,10 @@ func TestHostdexSpecificRequired(t *testing.T) { } func TestJavaSdkLibrary_RequireXmlPermissionFile(t *testing.T) { - ctx, _ := testJava(t, ` + result := javaFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo-shared_library", "foo-no_shared_library"), + ).RunTestWithBp(t, ` java_sdk_library { name: "foo-shared_library", srcs: ["a.java"], @@ -148,7 +151,7 @@ func TestJavaSdkLibrary_RequireXmlPermissionFile(t *testing.T) { `) // Verify the existence of internal modules - ctx.ModuleForTests("foo-shared_library.xml", "android_common") + result.ModuleForTests("foo-shared_library.xml", "android_common") testCases := []struct { moduleName string @@ -158,8 +161,8 @@ func TestJavaSdkLibrary_RequireXmlPermissionFile(t *testing.T) { {"foo-no_shared_library", nil}, } for _, tc := range testCases { - mod := ctx.ModuleForTests(tc.moduleName, "android_common").Module() - entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0] + mod := result.ModuleForTests(tc.moduleName, "android_common").Module() + entries := android.AndroidMkEntriesForTest(t, result.TestContext, mod)[0] actual := entries.EntryMap["LOCAL_REQUIRED_MODULES"] if !reflect.DeepEqual(tc.expected, actual) { t.Errorf("Unexpected required modules - expected: %q, actual: %q", tc.expected, actual) diff --git a/java/app.go b/java/app.go index eef627c14..1b6e0e3ee 100755 --- a/java/app.go +++ b/java/app.go @@ -302,7 +302,7 @@ func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) { // This check is enforced for "updatable" APKs (including APK-in-APEX). // b/155209650: until min_sdk_version is properly supported, use sdk_version instead. // because, sdk_version is overridden by min_sdk_version (if set as smaller) -// and linkType is checked with dependencies so we can be sure that the whole dependency tree +// and sdkLinkType is checked with dependencies so we can be sure that the whole dependency tree // will meet the requirements. func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion sdkVersion) { // It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType() @@ -1281,10 +1281,13 @@ func (u *usesLibrary) freezeEnforceUsesLibraries() { u.usesLibraryProperties.Enforce_uses_libs = &enforce } -// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against the ones specified -// in the uses_libs and optional_uses_libs properties. It returns the path to a copy of the manifest. -func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path { - outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml") +// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified +// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or +// an APK with the manifest embedded in it (manifest_check will know which one it is by the file +// extension: APKs are supposed to end with '.apk'). +func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path, + outputFile android.WritablePath) android.Path { + statusFile := dexpreopt.UsesLibrariesStatusFile(ctx) // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the @@ -1292,15 +1295,19 @@ func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, man // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to // various unrelated reasons, such as a failure to get manifest from an APK). if dexpreopt.GetGlobalConfig(ctx).DisablePreopt { - return manifest + return inputFile } rule := android.NewRuleBuilder(pctx, ctx) cmd := rule.Command().BuiltTool("manifest_check"). Flag("--enforce-uses-libraries"). - Input(manifest). + Input(inputFile). FlagWithOutput("--enforce-uses-libraries-status ", statusFile). - FlagWithOutput("-o ", outputFile) + FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt")) + + if outputFile != nil { + cmd.FlagWithOutput("-o ", outputFile) + } if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck { cmd.Flag("--enforce-uses-libraries-relax") @@ -1315,35 +1322,20 @@ func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, man } rule.Build("verify_uses_libraries", "verify <uses-library>") - return outputFile } -// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the ones specified -// in the uses_libs and optional_uses_libs properties. It returns the path to a copy of the APK. +// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against +// the build system and returns the path to a copy of the manifest. +func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path { + outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml") + return u.verifyUsesLibraries(ctx, manifest, outputFile) +} + +// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build +// system and returns the path to a copy of the APK. func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) android.Path { + u.verifyUsesLibraries(ctx, apk, nil) // for APKs manifest_check does not write output file outputFile := android.PathForModuleOut(ctx, "verify_uses_libraries", apk.Base()) - statusFile := dexpreopt.UsesLibrariesStatusFile(ctx) - - // Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the - // check is not necessary, and although it is good to have, it is difficult to maintain on - // non-linux build platforms where dexpreopt is generally disabled (the check may fail due to - // various unrelated reasons, such as a failure to get manifest from an APK). - if dexpreopt.GetGlobalConfig(ctx).DisablePreopt { - return apk - } - - rule := android.NewRuleBuilder(pctx, ctx) - aapt := ctx.Config().HostToolPath(ctx, "aapt") - rule.Command(). - Textf("aapt_binary=%s", aapt.String()).Implicit(aapt). - Textf(`uses_library_names="%s"`, strings.Join(u.usesLibraryProperties.Uses_libs, " ")). - Textf(`optional_uses_library_names="%s"`, strings.Join(u.usesLibraryProperties.Optional_uses_libs, " ")). - Textf(`relax_check="%t"`, dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck). - Tool(android.PathForSource(ctx, "build/make/core/verify_uses_libraries.sh")).Input(apk).Output(statusFile) - rule.Command().Text("cp -f").Input(apk).Output(outputFile) - - rule.Build("verify_uses_libraries", "verify <uses-library>") - return outputFile } diff --git a/java/app_test.go b/java/app_test.go index 3b37473ba..c189ee5d3 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -2400,13 +2400,13 @@ func TestUsesLibraries(t *testing.T) { // Test that all libraries are verified for an APK (library order matters). verifyApkCmd := prebuilt.Rule("verify_uses_libraries").RuleParams.Command - verifyApkReqLibs := `uses_library_names="foo com.non.sdk.lib android.test.runner"` - verifyApkOptLibs := `optional_uses_library_names="bar baz"` - if !strings.Contains(verifyApkCmd, verifyApkReqLibs) { - t.Errorf("wanted %q in %q", verifyApkReqLibs, verifyApkCmd) - } - if !strings.Contains(verifyApkCmd, verifyApkOptLibs) { - t.Errorf("wanted %q in %q", verifyApkOptLibs, verifyApkCmd) + verifyApkArgs := `--uses-library foo ` + + `--uses-library com.non.sdk.lib ` + + `--uses-library android.test.runner ` + + `--optional-uses-library bar ` + + `--optional-uses-library baz ` + if !strings.Contains(verifyApkCmd, verifyApkArgs) { + t.Errorf("wanted %q in %q", verifyApkArgs, verifyApkCmd) } // Test that all present libraries are preopted, including implicit SDK dependencies, possibly stubs diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go index 82e8b3f75..6ad4ff322 100644 --- a/java/hiddenapi_singleton.go +++ b/java/hiddenapi_singleton.go @@ -31,6 +31,8 @@ func RegisterHiddenApiSingletonComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("hiddenapi_flags", hiddenAPIFlagsFactory) } +var PrepareForTestWithHiddenApiBuildComponents = android.FixtureRegisterWithContext(RegisterHiddenApiSingletonComponents) + type hiddenAPISingletonPathsStruct struct { // The path to the CSV file that contains the flags that will be encoded into the dex boot jars. // diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go index fb63820a8..f17d436ae 100644 --- a/java/hiddenapi_singleton_test.go +++ b/java/hiddenapi_singleton_test.go @@ -16,68 +16,50 @@ package java import ( "fmt" - "strings" + "path/filepath" "testing" "android/soong/android" - "github.com/google/blueprint/proptools" ) -func testConfigWithBootJars(bp string, bootJars []string, prebuiltHiddenApiDir *string) android.Config { - config := testConfig(nil, bp, nil) - config.TestProductVariables.BootJars = android.CreateTestConfiguredJarList(bootJars) - config.TestProductVariables.PrebuiltHiddenApiDir = prebuiltHiddenApiDir - return config -} - -func testContextWithHiddenAPI(config android.Config) *android.TestContext { - ctx := testContext(config) - RegisterHiddenApiSingletonComponents(ctx) - return ctx -} - -func testHiddenAPIWithConfig(t *testing.T, config android.Config) *android.TestContext { - t.Helper() - - ctx := testContextWithHiddenAPI(config) - - run(t, ctx, config) - return ctx +func fixtureSetBootJarsProductVariable(bootJars ...string) android.FixturePreparer { + return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.BootJars = android.CreateTestConfiguredJarList(bootJars) + }) } -func testHiddenAPIBootJars(t *testing.T, bp string, bootJars []string, prebuiltHiddenApiDir *string) (*android.TestContext, android.Config) { - config := testConfigWithBootJars(bp, bootJars, prebuiltHiddenApiDir) - - return testHiddenAPIWithConfig(t, config), config +func fixtureSetPrebuiltHiddenApiDirProductVariable(prebuiltHiddenApiDir *string) android.FixturePreparer { + return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.PrebuiltHiddenApiDir = prebuiltHiddenApiDir + }) } -func testHiddenAPIUnbundled(t *testing.T, unbundled bool) (*android.TestContext, android.Config) { - config := testConfig(nil, ``, nil) - config.TestProductVariables.Always_use_prebuilt_sdks = proptools.BoolPtr(unbundled) - - return testHiddenAPIWithConfig(t, config), config -} +var hiddenApiFixtureFactory = javaFixtureFactory.Extend(PrepareForTestWithHiddenApiBuildComponents) func TestHiddenAPISingleton(t *testing.T) { - ctx, _ := testHiddenAPIBootJars(t, ` + result := hiddenApiFixtureFactory.Extend( + fixtureSetBootJarsProductVariable("platform:foo"), + ).RunTestWithBp(t, ` java_library { name: "foo", srcs: ["a.java"], compile_dex: true, } - `, []string{"platform:foo"}, nil) + `) - hiddenAPI := ctx.SingletonForTests("hiddenapi") + hiddenAPI := result.SingletonForTests("hiddenapi") hiddenapiRule := hiddenAPI.Rule("hiddenapi") want := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar" - if !strings.Contains(hiddenapiRule.RuleParams.Command, want) { - t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", want, hiddenapiRule.RuleParams.Command) - } + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want) } func TestHiddenAPIIndexSingleton(t *testing.T) { - ctx, _ := testHiddenAPIBootJars(t, ` + result := hiddenApiFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("bar"), + fixtureSetBootJarsProductVariable("platform:foo", "platform:bar"), + ).RunTestWithBp(t, ` java_library { name: "foo", srcs: ["a.java"], @@ -106,9 +88,9 @@ func TestHiddenAPIIndexSingleton(t *testing.T) { srcs: ["a.java"], compile_dex: true, } - `, []string{"platform:foo", "platform:bar"}, nil) + `) - hiddenAPIIndex := ctx.SingletonForTests("hiddenapi_index") + hiddenAPIIndex := result.SingletonForTests("hiddenapi_index") indexRule := hiddenAPIIndex.Rule("singleton-merged-hiddenapi-index") CheckHiddenAPIRuleInputs(t, ` .intermediates/bar/android_common/hiddenapi/index.csv @@ -118,7 +100,7 @@ func TestHiddenAPIIndexSingleton(t *testing.T) { // Make sure that the foo-hiddenapi-annotations.jar is included in the inputs to the rules that // creates the index.csv file. - foo := ctx.ModuleForTests("foo", "android_common") + foo := result.ModuleForTests("foo", "android_common") indexParams := foo.Output("hiddenapi/index.csv") CheckHiddenAPIRuleInputs(t, ` .intermediates/foo-hiddenapi-annotations/android_common/javac/foo-hiddenapi-annotations.jar @@ -127,7 +109,15 @@ func TestHiddenAPIIndexSingleton(t *testing.T) { } func TestHiddenAPISingletonWithSourceAndPrebuiltPreferredButNoDex(t *testing.T) { - config := testConfigWithBootJars(` + expectedErrorMessage := + "hiddenapi has determined that the source module \"foo\" should be ignored as it has been" + + " replaced by the prebuilt module \"prebuilt_foo\" but unfortunately it does not provide a" + + " suitable boot dex jar" + + hiddenApiFixtureFactory.Extend( + fixtureSetBootJarsProductVariable("platform:foo"), + ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(expectedErrorMessage)). + RunTestWithBp(t, ` java_library { name: "foo", srcs: ["a.java"], @@ -139,35 +129,30 @@ func TestHiddenAPISingletonWithSourceAndPrebuiltPreferredButNoDex(t *testing.T) jars: ["a.jar"], prefer: true, } - `, []string{"platform:foo"}, nil) - - ctx := testContextWithHiddenAPI(config) - - runWithErrors(t, ctx, config, - "hiddenapi has determined that the source module \"foo\" should be ignored as it has been"+ - " replaced by the prebuilt module \"prebuilt_foo\" but unfortunately it does not provide a"+ - " suitable boot dex jar") + `) } func TestHiddenAPISingletonWithPrebuilt(t *testing.T) { - ctx, _ := testHiddenAPIBootJars(t, ` + result := hiddenApiFixtureFactory.Extend( + fixtureSetBootJarsProductVariable("platform:foo"), + ).RunTestWithBp(t, ` java_import { name: "foo", jars: ["a.jar"], compile_dex: true, } - `, []string{"platform:foo"}, nil) + `) - hiddenAPI := ctx.SingletonForTests("hiddenapi") + hiddenAPI := result.SingletonForTests("hiddenapi") hiddenapiRule := hiddenAPI.Rule("hiddenapi") want := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar" - if !strings.Contains(hiddenapiRule.RuleParams.Command, want) { - t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", want, hiddenapiRule.RuleParams.Command) - } + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want) } func TestHiddenAPISingletonWithPrebuiltUseSource(t *testing.T) { - ctx, _ := testHiddenAPIBootJars(t, ` + result := hiddenApiFixtureFactory.Extend( + fixtureSetBootJarsProductVariable("platform:foo"), + ).RunTestWithBp(t, ` java_library { name: "foo", srcs: ["a.java"], @@ -180,23 +165,21 @@ func TestHiddenAPISingletonWithPrebuiltUseSource(t *testing.T) { compile_dex: true, prefer: false, } - `, []string{"platform:foo"}, nil) + `) - hiddenAPI := ctx.SingletonForTests("hiddenapi") + hiddenAPI := result.SingletonForTests("hiddenapi") hiddenapiRule := hiddenAPI.Rule("hiddenapi") fromSourceJarArg := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar" - if !strings.Contains(hiddenapiRule.RuleParams.Command, fromSourceJarArg) { - t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", fromSourceJarArg, hiddenapiRule.RuleParams.Command) - } + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, fromSourceJarArg) prebuiltJarArg := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/dex/foo.jar" - if strings.Contains(hiddenapiRule.RuleParams.Command, prebuiltJarArg) { - t.Errorf("Did not expect %s in hiddenapi command, but it was present: %s", prebuiltJarArg, hiddenapiRule.RuleParams.Command) - } + android.AssertStringDoesNotContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, prebuiltJarArg) } func TestHiddenAPISingletonWithPrebuiltOverrideSource(t *testing.T) { - ctx, _ := testHiddenAPIBootJars(t, ` + result := hiddenApiFixtureFactory.Extend( + fixtureSetBootJarsProductVariable("platform:foo"), + ).RunTestWithBp(t, ` java_library { name: "foo", srcs: ["a.java"], @@ -209,19 +192,15 @@ func TestHiddenAPISingletonWithPrebuiltOverrideSource(t *testing.T) { compile_dex: true, prefer: true, } - `, []string{"platform:foo"}, nil) + `) - hiddenAPI := ctx.SingletonForTests("hiddenapi") + hiddenAPI := result.SingletonForTests("hiddenapi") hiddenapiRule := hiddenAPI.Rule("hiddenapi") prebuiltJarArg := "--boot-dex=" + buildDir + "/.intermediates/prebuilt_foo/android_common/dex/foo.jar" - if !strings.Contains(hiddenapiRule.RuleParams.Command, prebuiltJarArg) { - t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", prebuiltJarArg, hiddenapiRule.RuleParams.Command) - } + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, prebuiltJarArg) fromSourceJarArg := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar" - if strings.Contains(hiddenapiRule.RuleParams.Command, fromSourceJarArg) { - t.Errorf("Did not expect %s in hiddenapi command, but it was present: %s", fromSourceJarArg, hiddenapiRule.RuleParams.Command) - } + android.AssertStringDoesNotContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, fromSourceJarArg) } func TestHiddenAPISingletonSdks(t *testing.T) { @@ -232,6 +211,9 @@ func TestHiddenAPISingletonSdks(t *testing.T) { systemStub string testStub string corePlatformStub string + + // Additional test preparer + preparer android.FixturePreparer }{ { name: "testBundled", @@ -240,6 +222,7 @@ func TestHiddenAPISingletonSdks(t *testing.T) { systemStub: "android_system_stubs_current", testStub: "android_test_stubs_current", corePlatformStub: "legacy.core.platform.api.stubs", + preparer: android.GroupFixturePreparers(), }, { name: "testUnbundled", unbundledBuild: true, @@ -247,33 +230,31 @@ func TestHiddenAPISingletonSdks(t *testing.T) { systemStub: "sdk_system_current_android", testStub: "sdk_test_current_android", corePlatformStub: "legacy.core.platform.api.stubs", + preparer: PrepareForTestWithPrebuiltsOfCurrentApi, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - ctx, _ := testHiddenAPIUnbundled(t, tc.unbundledBuild) - - hiddenAPI := ctx.SingletonForTests("hiddenapi") + result := hiddenApiFixtureFactory.Extend( + tc.preparer, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.Always_use_prebuilt_sdks = proptools.BoolPtr(tc.unbundledBuild) + }), + ).RunTest(t) + + hiddenAPI := result.SingletonForTests("hiddenapi") hiddenapiRule := hiddenAPI.Rule("hiddenapi") wantPublicStubs := "--public-stub-classpath=" + generateSdkDexPath(tc.publicStub, tc.unbundledBuild) - if !strings.Contains(hiddenapiRule.RuleParams.Command, wantPublicStubs) { - t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", wantPublicStubs, hiddenapiRule.RuleParams.Command) - } + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantPublicStubs) wantSystemStubs := "--system-stub-classpath=" + generateSdkDexPath(tc.systemStub, tc.unbundledBuild) - if !strings.Contains(hiddenapiRule.RuleParams.Command, wantSystemStubs) { - t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", wantSystemStubs, hiddenapiRule.RuleParams.Command) - } + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantSystemStubs) wantTestStubs := "--test-stub-classpath=" + generateSdkDexPath(tc.testStub, tc.unbundledBuild) - if !strings.Contains(hiddenapiRule.RuleParams.Command, wantTestStubs) { - t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", wantTestStubs, hiddenapiRule.RuleParams.Command) - } - - wantCorePlatformStubs := "--core-platform-stub-classpath=" + generateDexPath(tc.corePlatformStub) - if !strings.Contains(hiddenapiRule.RuleParams.Command, wantCorePlatformStubs) { - t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", wantCorePlatformStubs, hiddenapiRule.RuleParams.Command) - } + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantTestStubs) + + wantCorePlatformStubs := "--core-platform-stub-classpath=" + generateDexPath(defaultJavaDir, tc.corePlatformStub) + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantCorePlatformStubs) }) } } @@ -282,15 +263,15 @@ func generateDexedPath(subDir, dex, module string) string { return fmt.Sprintf("%s/.intermediates/%s/android_common/%s/%s.jar", buildDir, subDir, dex, module) } -func generateDexPath(module string) string { - return generateDexedPath(module, "dex", module) +func generateDexPath(moduleDir string, module string) string { + return generateDexedPath(filepath.Join(moduleDir, module), "dex", module) } func generateSdkDexPath(module string, unbundled bool) string { if unbundled { return generateDexedPath("prebuilts/sdk/"+module, "dex", module) } - return generateDexPath(module) + return generateDexPath(defaultJavaDir, module) } func TestHiddenAPISingletonWithPrebuiltCsvFile(t *testing.T) { @@ -304,36 +285,33 @@ func TestHiddenAPISingletonWithPrebuiltCsvFile(t *testing.T) { // Where to find the prebuilt hiddenapi files: prebuiltHiddenApiDir := "path/to/prebuilt/hiddenapi" - ctx, _ := testHiddenAPIBootJars(t, ` + result := hiddenApiFixtureFactory.Extend( + fixtureSetBootJarsProductVariable("platform:foo"), + fixtureSetPrebuiltHiddenApiDirProductVariable(&prebuiltHiddenApiDir), + ).RunTestWithBp(t, ` java_import { name: "foo", jars: ["a.jar"], compile_dex: true, } - `, []string{"platform:foo"}, &prebuiltHiddenApiDir) + `) expectedCpInput := prebuiltHiddenApiDir + "/hiddenapi-flags.csv" expectedCpOutput := buildDir + "/hiddenapi/hiddenapi-flags.csv" expectedFlagsCsv := buildDir + "/hiddenapi/hiddenapi-flags.csv" - foo := ctx.ModuleForTests("foo", "android_common") + foo := result.ModuleForTests("foo", "android_common") - hiddenAPI := ctx.SingletonForTests("hiddenapi") + hiddenAPI := result.SingletonForTests("hiddenapi") cpRule := hiddenAPI.Rule("Cp") actualCpInput := cpRule.BuildParams.Input actualCpOutput := cpRule.BuildParams.Output encodeDexRule := foo.Rule("hiddenAPIEncodeDex") actualFlagsCsv := encodeDexRule.BuildParams.Args["flagsCsv"] - if actualCpInput.String() != expectedCpInput { - t.Errorf("Prebuilt hiddenapi cp rule input mismatch, actual: %s, expected: %s", actualCpInput, expectedCpInput) - } + android.AssertStringEquals(t, "hiddenapi cp rule input", expectedCpInput, actualCpInput.String()) - if actualCpOutput.String() != expectedCpOutput { - t.Errorf("Prebuilt hiddenapi cp rule output mismatch, actual: %s, expected: %s", actualCpOutput, expectedCpOutput) - } + android.AssertStringEquals(t, "hiddenapi cp rule output", expectedCpOutput, actualCpOutput.String()) - if actualFlagsCsv != expectedFlagsCsv { - t.Errorf("Prebuilt hiddenapi encode dex rule flags csv mismatch, actual: %s, expected: %s", actualFlagsCsv, expectedFlagsCsv) - } + android.AssertStringEquals(t, "hiddenapi encode dex rule flags csv", expectedFlagsCsv, actualFlagsCsv) } diff --git a/java/java.go b/java/java.go index 036c7afd4..8c714eeb2 100644 --- a/java/java.go +++ b/java/java.go @@ -37,6 +37,36 @@ import ( func init() { RegisterJavaBuildComponents(android.InitRegistrationContext) + RegisterJavaSdkMemberTypes() +} + +func RegisterJavaBuildComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("java_defaults", DefaultsFactory) + + ctx.RegisterModuleType("java_library", LibraryFactory) + ctx.RegisterModuleType("java_library_static", LibraryStaticFactory) + ctx.RegisterModuleType("java_library_host", LibraryHostFactory) + ctx.RegisterModuleType("java_binary", BinaryFactory) + ctx.RegisterModuleType("java_binary_host", BinaryHostFactory) + ctx.RegisterModuleType("java_test", TestFactory) + ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory) + ctx.RegisterModuleType("java_test_host", TestHostFactory) + ctx.RegisterModuleType("java_test_import", JavaTestImportFactory) + ctx.RegisterModuleType("java_import", ImportFactory) + ctx.RegisterModuleType("java_import_host", ImportFactoryHost) + ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory) + ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory) + ctx.RegisterModuleType("dex_import", DexImportFactory) + + ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { + ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel() + }) + + ctx.RegisterSingletonType("logtags", LogtagsSingleton) + ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory) +} + +func RegisterJavaSdkMemberTypes() { // Register sdk member types. android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType) @@ -89,85 +119,7 @@ func init() { PropertyName: "java_tests", }, }) -} - -func RegisterJavaBuildComponents(ctx android.RegistrationContext) { - ctx.RegisterModuleType("java_defaults", DefaultsFactory) - - ctx.RegisterModuleType("java_library", LibraryFactory) - ctx.RegisterModuleType("java_library_static", LibraryStaticFactory) - ctx.RegisterModuleType("java_library_host", LibraryHostFactory) - ctx.RegisterModuleType("java_binary", BinaryFactory) - ctx.RegisterModuleType("java_binary_host", BinaryHostFactory) - ctx.RegisterModuleType("java_test", TestFactory) - ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory) - ctx.RegisterModuleType("java_test_host", TestHostFactory) - ctx.RegisterModuleType("java_test_import", JavaTestImportFactory) - ctx.RegisterModuleType("java_import", ImportFactory) - ctx.RegisterModuleType("java_import_host", ImportFactoryHost) - ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory) - ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory) - ctx.RegisterModuleType("dex_import", DexImportFactory) - - ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { - ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel() - }) - - ctx.RegisterSingletonType("logtags", LogtagsSingleton) - ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory) -} - -func (j *Module) CheckStableSdkVersion() error { - sdkVersion := j.sdkVersion() - if sdkVersion.stable() { - return nil - } - if sdkVersion.kind == sdkCorePlatform { - if useLegacyCorePlatformApiByName(j.BaseModuleName()) { - return fmt.Errorf("non stable SDK %v - uses legacy core platform", sdkVersion) - } else { - // Treat stable core platform as stable. - return nil - } - } else { - return fmt.Errorf("non stable SDK %v", sdkVersion) - } -} - -func (j *Module) checkSdkVersions(ctx android.ModuleContext) { - if j.RequiresStableAPIs(ctx) { - if sc, ok := ctx.Module().(sdkContext); ok { - if !sc.sdkVersion().specified() { - ctx.PropertyErrorf("sdk_version", - "sdk_version must have a value when the module is located at vendor or product(only if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is set).") - } - } - } - - ctx.VisitDirectDeps(func(module android.Module) { - tag := ctx.OtherModuleDependencyTag(module) - switch module.(type) { - // TODO(satayev): cover other types as well, e.g. imports - case *Library, *AndroidLibrary: - switch tag { - case bootClasspathTag, libTag, staticLibTag, java9LibTag: - checkLinkType(ctx, j, module.(linkTypeContext), tag.(dependencyTag)) - } - } - }) -} -func (j *Module) checkPlatformAPI(ctx android.ModuleContext) { - if sc, ok := ctx.Module().(sdkContext); ok { - usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis) - sdkVersionSpecified := sc.sdkVersion().specified() - if usePlatformAPI && sdkVersionSpecified { - ctx.PropertyErrorf("platform_apis", "platform_apis must be false when sdk_version is not empty.") - } else if !usePlatformAPI && !sdkVersionSpecified { - ctx.PropertyErrorf("platform_apis", "platform_apis must be true when sdk_version is empty.") - } - - } } // TODO: @@ -179,7 +131,8 @@ func (j *Module) checkPlatformAPI(ctx android.ModuleContext) { // DroidDoc // Findbugs -type CompilerProperties struct { +// Properties that are common to most Java modules, i.e. whether it's a host or device module. +type CommonProperties struct { // list of source files used to compile the Java module. May be .java, .kt, .logtags, .proto, // or .aidl files. Srcs []string `android:"path,arch_variant"` @@ -312,7 +265,9 @@ type CompilerProperties struct { Hiddenapi_additional_annotations []string } -type CompilerDeviceProperties struct { +// Properties that are specific to device modules. Host module factories should not add these when +// constructing a new module. +type DeviceProperties struct { // if not blank, set to the version of the sdk to compile against. // Defaults to compiling against the current platform. Sdk_version *string @@ -421,9 +376,9 @@ type Module struct { // Functionality common to Module and Import. embeddableInModuleAndImport - properties CompilerProperties + properties CommonProperties protoProperties android.ProtoProperties - deviceProperties CompilerDeviceProperties + deviceProperties DeviceProperties // jar file containing header classes including static library dependencies, suitable for // inserting into the bootclasspath/classpath of another compile @@ -508,6 +463,62 @@ type Module struct { hideApexVariantFromMake bool } +func (j *Module) CheckStableSdkVersion() error { + sdkVersion := j.sdkVersion() + if sdkVersion.stable() { + return nil + } + if sdkVersion.kind == sdkCorePlatform { + if useLegacyCorePlatformApiByName(j.BaseModuleName()) { + return fmt.Errorf("non stable SDK %v - uses legacy core platform", sdkVersion) + } else { + // Treat stable core platform as stable. + return nil + } + } else { + return fmt.Errorf("non stable SDK %v", sdkVersion) + } +} + +// checkSdkVersions enforces restrictions around SDK dependencies. +func (j *Module) checkSdkVersions(ctx android.ModuleContext) { + if j.RequiresStableAPIs(ctx) { + if sc, ok := ctx.Module().(sdkContext); ok { + if !sc.sdkVersion().specified() { + ctx.PropertyErrorf("sdk_version", + "sdk_version must have a value when the module is located at vendor or product(only if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is set).") + } + } + } + + // Make sure this module doesn't statically link to modules with lower-ranked SDK link type. + // See rank() for details. + ctx.VisitDirectDeps(func(module android.Module) { + tag := ctx.OtherModuleDependencyTag(module) + switch module.(type) { + // TODO(satayev): cover other types as well, e.g. imports + case *Library, *AndroidLibrary: + switch tag { + case bootClasspathTag, libTag, staticLibTag, java9LibTag: + j.checkSdkLinkType(ctx, module.(moduleWithSdkDep), tag.(dependencyTag)) + } + } + }) +} + +func (j *Module) checkPlatformAPI(ctx android.ModuleContext) { + if sc, ok := ctx.Module().(sdkContext); ok { + usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis) + sdkVersionSpecified := sc.sdkVersion().specified() + if usePlatformAPI && sdkVersionSpecified { + ctx.PropertyErrorf("platform_apis", "platform_apis must be false when sdk_version is not empty.") + } else if !usePlatformAPI && !sdkVersionSpecified { + ctx.PropertyErrorf("platform_apis", "platform_apis must be true when sdk_version is empty.") + } + + } +} + func (j *Module) addHostProperties() { j.AddProperties( &j.properties, @@ -1008,13 +1019,13 @@ func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer } } -type linkType int +type sdkLinkType int const ( // TODO(jiyong) rename these for better readability. Make the allowed // and disallowed link types explicit // order is important here. See rank() - javaCore linkType = iota + javaCore sdkLinkType = iota javaSdk javaSystem javaModule @@ -1022,7 +1033,7 @@ const ( javaPlatform ) -func (lt linkType) String() string { +func (lt sdkLinkType) String() string { switch lt { case javaCore: return "core Java API" @@ -1041,18 +1052,19 @@ func (lt linkType) String() string { } } -// rank determins the total order among linkTypes. A link type of rank A can link to another link -// type of rank B only when B <= A -func (lt linkType) rank() int { +// rank determines the total order among sdkLinkType. An SDK link type of rank A can link to +// another SDK link type of rank B only when B <= A. For example, a module linking to Android SDK +// can't statically depend on modules that use Platform API. +func (lt sdkLinkType) rank() int { return int(lt) } -type linkTypeContext interface { +type moduleWithSdkDep interface { android.Module - getLinkType(name string) (ret linkType, stubs bool) + getSdkLinkType(name string) (ret sdkLinkType, stubs bool) } -func (m *Module) getLinkType(name string) (ret linkType, stubs bool) { +func (m *Module) getSdkLinkType(name string) (ret sdkLinkType, stubs bool) { switch name { case "core.current.stubs", "legacy.core.platform.api.stubs", "stable.core.platform.api.stubs", "stub-annotations", "private-stub-annotations-jar", @@ -1096,23 +1108,26 @@ func (m *Module) getLinkType(name string) (ret linkType, stubs bool) { return javaSdk, false } -func checkLinkType(ctx android.ModuleContext, from *Module, to linkTypeContext, tag dependencyTag) { +// checkSdkLinkType make sures the given dependency doesn't have a lower SDK link type rank than +// this module's. See the comment on rank() for details and an example. +func (j *Module) checkSdkLinkType( + ctx android.ModuleContext, dep moduleWithSdkDep, tag dependencyTag) { if ctx.Host() { return } - myLinkType, stubs := from.getLinkType(ctx.ModuleName()) + myLinkType, stubs := j.getSdkLinkType(ctx.ModuleName()) if stubs { return } - otherLinkType, _ := to.getLinkType(ctx.OtherModuleName(to)) + depLinkType, _ := dep.getSdkLinkType(ctx.OtherModuleName(dep)) - if myLinkType.rank() < otherLinkType.rank() { + if myLinkType.rank() < depLinkType.rank() { ctx.ModuleErrorf("compiles against %v, but dependency %q is compiling against %v. "+ "In order to fix this, consider adjusting sdk_version: OR platform_apis: "+ "property of the source or target module so that target module is built "+ "with the same or smaller API set when compared to the source.", - myLinkType, ctx.OtherModuleName(to), otherLinkType) + myLinkType, ctx.OtherModuleName(dep), depLinkType) } } @@ -1133,7 +1148,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { } } - linkType, _ := j.getLinkType(ctx.ModuleName()) + sdkLinkType, _ := j.getSdkLinkType(ctx.ModuleName()) ctx.VisitDirectDeps(func(module android.Module) { otherName := ctx.OtherModuleName(module) @@ -1157,7 +1172,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { } } else if ctx.OtherModuleHasProvider(module, JavaInfoProvider) { dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo) - if linkType != javaPlatform && + if sdkLinkType != javaPlatform && ctx.OtherModuleHasProvider(module, SyspropPublicStubInfoProvider) { // dep is a sysprop implementation library, but this module is not linking against // the platform, so it gets the sysprop public stubs library instead. Replace @@ -2505,6 +2520,10 @@ func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { j.deps(ctx) } +func (j *TestHost) AddExtraResource(p android.Path) { + j.extraResources = append(j.extraResources, p) +} + func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { if j.testProperties.Test_options.Unit_test == nil && ctx.Host() { // TODO(b/): Clean temporary heuristic to avoid unexpected onboarding. @@ -2668,13 +2687,23 @@ func TestHostFactory() android.Module { module.AddProperties(&module.testProperties) module.AddProperties(&module.testHostProperties) - module.Module.properties.Installable = proptools.BoolPtr(true) + InitTestHost( + module, + proptools.BoolPtr(true), + nil, + nil) InitJavaModuleMultiTargets(module, android.HostSupported) return module } +func InitTestHost(th *TestHost, installable *bool, testSuites []string, autoGenConfig *bool) { + th.properties.Installable = installable + th.testProperties.Auto_gen_config = autoGenConfig + th.testProperties.Test_suites = testSuites +} + // // Java Binaries (.jar file plus wrapper script) // @@ -3332,8 +3361,8 @@ func DefaultsFactory() android.Module { module := &Defaults{} module.AddProperties( - &CompilerProperties{}, - &CompilerDeviceProperties{}, + &CommonProperties{}, + &DeviceProperties{}, &DexProperties{}, &DexpreoptProperties{}, &android.ProtoProperties{}, diff --git a/java/java_test.go b/java/java_test.go index 9ef23e9a9..2eb724185 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -369,13 +369,9 @@ func TestSimple(t *testing.T) { barTurbine := filepath.Join(buildDir, ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar") bazTurbine := filepath.Join(buildDir, ".intermediates", "baz", "android_common", "turbine-combined", "baz.jar") - if !strings.Contains(javac.Args["classpath"], barTurbine) { - t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barTurbine) - } + android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], barTurbine) - if !strings.Contains(javac.Args["classpath"], bazTurbine) { - t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bazTurbine) - } + android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], bazTurbine) if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz { t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz) @@ -745,7 +741,7 @@ prebuilt_stubs_sources { } func TestJavaSdkLibraryImport(t *testing.T) { - ctx, _ := testJava(t, ` + result := javaFixtureFactory.RunTestWithBp(t, ` java_library { name: "foo", srcs: ["a.java"], @@ -783,16 +779,14 @@ func TestJavaSdkLibraryImport(t *testing.T) { `) for _, scope := range []string{"", ".system", ".test"} { - fooModule := ctx.ModuleForTests("foo"+scope, "android_common") + fooModule := result.ModuleForTests("foo"+scope, "android_common") javac := fooModule.Rule("javac") - sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs"+scope, "android_common").Rule("combineJar").Output - if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) { - t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], sdklibStubsJar.String()) - } + sdklibStubsJar := result.ModuleForTests("sdklib.stubs"+scope, "android_common").Rule("combineJar").Output + android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], sdklibStubsJar.String()) } - CheckModuleDependencies(t, ctx, "sdklib", "android_common", []string{ + CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ `prebuilt_sdklib.stubs`, `prebuilt_sdklib.stubs.source.test`, `prebuilt_sdklib.stubs.system`, @@ -801,7 +795,10 @@ func TestJavaSdkLibraryImport(t *testing.T) { } func TestJavaSdkLibraryImport_WithSource(t *testing.T) { - ctx, _ := testJava(t, ` + result := javaFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("sdklib"), + ).RunTestWithBp(t, ` java_sdk_library { name: "sdklib", srcs: ["a.java"], @@ -820,7 +817,7 @@ func TestJavaSdkLibraryImport_WithSource(t *testing.T) { } `) - CheckModuleDependencies(t, ctx, "sdklib", "android_common", []string{ + CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ `dex2oatd`, `prebuilt_sdklib`, `sdklib.impl`, @@ -829,7 +826,7 @@ func TestJavaSdkLibraryImport_WithSource(t *testing.T) { `sdklib.xml`, }) - CheckModuleDependencies(t, ctx, "prebuilt_sdklib", "android_common", []string{ + CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{ `prebuilt_sdklib.stubs`, `sdklib.impl`, // This should be prebuilt_sdklib.stubs but is set to sdklib.stubs because the @@ -840,7 +837,10 @@ func TestJavaSdkLibraryImport_WithSource(t *testing.T) { } func TestJavaSdkLibraryImport_Preferred(t *testing.T) { - ctx, _ := testJava(t, ` + result := javaFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("sdklib"), + ).RunTestWithBp(t, ` java_sdk_library { name: "sdklib", srcs: ["a.java"], @@ -860,7 +860,7 @@ func TestJavaSdkLibraryImport_Preferred(t *testing.T) { } `) - CheckModuleDependencies(t, ctx, "sdklib", "android_common", []string{ + CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ `dex2oatd`, `prebuilt_sdklib`, `sdklib.impl`, @@ -869,7 +869,7 @@ func TestJavaSdkLibraryImport_Preferred(t *testing.T) { `sdklib.xml`, }) - CheckModuleDependencies(t, ctx, "prebuilt_sdklib", "android_common", []string{ + CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{ `prebuilt_sdklib.stubs`, `sdklib.impl`, `sdklib.xml`, @@ -924,6 +924,8 @@ func TestJavaSdkLibraryEnforce(t *testing.T) { partitionToBpOption(info.toPartition)) return android.GroupFixturePreparers( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("bar"), android.FixtureWithRootAndroidBp(bpFile), android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { variables.EnforceProductPartitionInterface = proptools.BoolPtr(info.enforceProductInterface) @@ -1844,7 +1846,14 @@ func TestJavaImport(t *testing.T) { } func TestJavaSdkLibrary(t *testing.T) { - ctx, _ := testJava(t, ` + result := javaFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithPrebuiltApis(map[string][]string{ + "28": {"foo"}, + "29": {"foo"}, + "30": {"bar", "barney", "baz", "betty", "foo", "fred", "quuz", "wilma"}, + }), + ).RunTestWithBp(t, ` droiddoc_exported_dir { name: "droiddoc-templates-sdk", path: ".", @@ -1921,68 +1930,51 @@ func TestJavaSdkLibrary(t *testing.T) { `) // check the existence of the internal modules - ctx.ModuleForTests("foo", "android_common") - ctx.ModuleForTests(apiScopePublic.stubsLibraryModuleName("foo"), "android_common") - ctx.ModuleForTests(apiScopeSystem.stubsLibraryModuleName("foo"), "android_common") - ctx.ModuleForTests(apiScopeTest.stubsLibraryModuleName("foo"), "android_common") - ctx.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo"), "android_common") - ctx.ModuleForTests(apiScopeSystem.stubsSourceModuleName("foo"), "android_common") - ctx.ModuleForTests(apiScopeTest.stubsSourceModuleName("foo"), "android_common") - ctx.ModuleForTests("foo"+sdkXmlFileSuffix, "android_common") - ctx.ModuleForTests("foo.api.public.28", "") - ctx.ModuleForTests("foo.api.system.28", "") - ctx.ModuleForTests("foo.api.test.28", "") - - bazJavac := ctx.ModuleForTests("baz", "android_common").Rule("javac") + result.ModuleForTests("foo", "android_common") + result.ModuleForTests(apiScopePublic.stubsLibraryModuleName("foo"), "android_common") + result.ModuleForTests(apiScopeSystem.stubsLibraryModuleName("foo"), "android_common") + result.ModuleForTests(apiScopeTest.stubsLibraryModuleName("foo"), "android_common") + result.ModuleForTests(apiScopePublic.stubsSourceModuleName("foo"), "android_common") + result.ModuleForTests(apiScopeSystem.stubsSourceModuleName("foo"), "android_common") + result.ModuleForTests(apiScopeTest.stubsSourceModuleName("foo"), "android_common") + result.ModuleForTests("foo"+sdkXmlFileSuffix, "android_common") + result.ModuleForTests("foo.api.public.28", "") + result.ModuleForTests("foo.api.system.28", "") + result.ModuleForTests("foo.api.test.28", "") + + bazJavac := result.ModuleForTests("baz", "android_common").Rule("javac") // tests if baz is actually linked to the stubs lib - if !strings.Contains(bazJavac.Args["classpath"], "foo.stubs.system.jar") { - t.Errorf("baz javac classpath %v does not contain %q", bazJavac.Args["classpath"], - "foo.stubs.system.jar") - } + android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.system.jar") // ... and not to the impl lib - if strings.Contains(bazJavac.Args["classpath"], "foo.jar") { - t.Errorf("baz javac classpath %v should not contain %q", bazJavac.Args["classpath"], - "foo.jar") - } + android.AssertStringDoesNotContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.jar") // test if baz is not linked to the system variant of foo - if strings.Contains(bazJavac.Args["classpath"], "foo.stubs.jar") { - t.Errorf("baz javac classpath %v should not contain %q", bazJavac.Args["classpath"], - "foo.stubs.jar") - } + android.AssertStringDoesNotContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.jar") - bazTestJavac := ctx.ModuleForTests("baz-test", "android_common").Rule("javac") + bazTestJavac := result.ModuleForTests("baz-test", "android_common").Rule("javac") // tests if baz-test is actually linked to the test stubs lib - if !strings.Contains(bazTestJavac.Args["classpath"], "foo.stubs.test.jar") { - t.Errorf("baz-test javac classpath %v does not contain %q", bazTestJavac.Args["classpath"], - "foo.stubs.test.jar") - } + android.AssertStringDoesContain(t, "baz-test javac classpath", bazTestJavac.Args["classpath"], "foo.stubs.test.jar") - baz29Javac := ctx.ModuleForTests("baz-29", "android_common").Rule("javac") + baz29Javac := result.ModuleForTests("baz-29", "android_common").Rule("javac") // tests if baz-29 is actually linked to the system 29 stubs lib - if !strings.Contains(baz29Javac.Args["classpath"], "prebuilts/sdk/29/system/foo.jar") { - t.Errorf("baz-29 javac classpath %v does not contain %q", baz29Javac.Args["classpath"], - "prebuilts/sdk/29/system/foo.jar") - } + android.AssertStringDoesContain(t, "baz-29 javac classpath", baz29Javac.Args["classpath"], "prebuilts/sdk/29/system/foo.jar") - bazModule30Javac := ctx.ModuleForTests("baz-module-30", "android_common").Rule("javac") + bazModule30Javac := result.ModuleForTests("baz-module-30", "android_common").Rule("javac") // tests if "baz-module-30" is actually linked to the module 30 stubs lib - if !strings.Contains(bazModule30Javac.Args["classpath"], "prebuilts/sdk/30/module-lib/foo.jar") { - t.Errorf("baz-module-30 javac classpath %v does not contain %q", bazModule30Javac.Args["classpath"], - "prebuilts/sdk/30/module-lib/foo.jar") - } + android.AssertStringDoesContain(t, "baz-module-30 javac classpath", bazModule30Javac.Args["classpath"], "prebuilts/sdk/30/module-lib/foo.jar") // test if baz has exported SDK lib names foo and bar to qux - qux := ctx.ModuleForTests("qux", "android_common") + qux := result.ModuleForTests("qux", "android_common") if quxLib, ok := qux.Module().(*Library); ok { sdkLibs := quxLib.ClassLoaderContexts().UsesLibs() - if w := []string{"foo", "bar", "fred", "quuz"}; !reflect.DeepEqual(w, sdkLibs) { - t.Errorf("qux should export %q but exports %q", w, sdkLibs) - } + android.AssertDeepEquals(t, "qux exports", []string{"foo", "bar", "fred", "quuz"}, sdkLibs) } } func TestJavaSdkLibrary_StubOrImplOnlyLibs(t *testing.T) { - ctx, _ := testJava(t, ` + result := javaFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("sdklib"), + ).RunTestWithBp(t, ` java_sdk_library { name: "sdklib", srcs: ["a.java"], @@ -2002,20 +1994,23 @@ func TestJavaSdkLibrary_StubOrImplOnlyLibs(t *testing.T) { `) for _, implName := range []string{"sdklib", "sdklib.impl"} { - implJavacCp := ctx.ModuleForTests(implName, "android_common").Rule("javac").Args["classpath"] + implJavacCp := result.ModuleForTests(implName, "android_common").Rule("javac").Args["classpath"] if !strings.Contains(implJavacCp, "/foo.jar") || strings.Contains(implJavacCp, "/bar.jar") { t.Errorf("%v javac classpath %v does not contain foo and not bar", implName, implJavacCp) } } stubName := apiScopePublic.stubsLibraryModuleName("sdklib") - stubsJavacCp := ctx.ModuleForTests(stubName, "android_common").Rule("javac").Args["classpath"] + stubsJavacCp := result.ModuleForTests(stubName, "android_common").Rule("javac").Args["classpath"] if strings.Contains(stubsJavacCp, "/foo.jar") || !strings.Contains(stubsJavacCp, "/bar.jar") { t.Errorf("stubs javac classpath %v does not contain bar and not foo", stubsJavacCp) } } func TestJavaSdkLibrary_DoNotAccessImplWhenItIsNotBuilt(t *testing.T) { - ctx, _ := testJava(t, ` + result := javaFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo"), + ).RunTestWithBp(t, ` java_sdk_library { name: "foo", srcs: ["a.java"], @@ -2033,14 +2028,17 @@ func TestJavaSdkLibrary_DoNotAccessImplWhenItIsNotBuilt(t *testing.T) { `) // The bar library should depend on the stubs jar. - barLibrary := ctx.ModuleForTests("bar", "android_common").Rule("javac") + barLibrary := result.ModuleForTests("bar", "android_common").Rule("javac") if expected, actual := `^-classpath .*:/[^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { t.Errorf("expected %q, found %#q", expected, actual) } } func TestJavaSdkLibrary_UseSourcesFromAnotherSdkLibrary(t *testing.T) { - testJava(t, ` + javaFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo"), + ).RunTestWithBp(t, ` java_sdk_library { name: "foo", srcs: ["a.java"], @@ -2058,7 +2056,13 @@ func TestJavaSdkLibrary_UseSourcesFromAnotherSdkLibrary(t *testing.T) { } func TestJavaSdkLibrary_AccessOutputFiles_MissingScope(t *testing.T) { - testJavaError(t, `"foo" does not provide api scope system`, ` + javaFixtureFactory. + Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo"), + ). + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`"foo" does not provide api scope system`)). + RunTestWithBp(t, ` java_sdk_library { name: "foo", srcs: ["a.java"], @@ -2076,7 +2080,10 @@ func TestJavaSdkLibrary_AccessOutputFiles_MissingScope(t *testing.T) { } func TestJavaSdkLibrary_Deps(t *testing.T) { - ctx, _ := testJava(t, ` + result := javaFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("sdklib"), + ).RunTestWithBp(t, ` java_sdk_library { name: "sdklib", srcs: ["a.java"], @@ -2088,7 +2095,7 @@ func TestJavaSdkLibrary_Deps(t *testing.T) { } `) - CheckModuleDependencies(t, ctx, "sdklib", "android_common", []string{ + CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ `dex2oatd`, `sdklib.impl`, `sdklib.stubs`, @@ -2098,7 +2105,7 @@ func TestJavaSdkLibrary_Deps(t *testing.T) { } func TestJavaSdkLibraryImport_AccessOutputFiles(t *testing.T) { - testJava(t, ` + javaFixtureFactory.RunTestWithBp(t, ` java_sdk_library_import { name: "foo", public: { @@ -2131,63 +2138,74 @@ func TestJavaSdkLibraryImport_AccessOutputFiles_Invalid(t *testing.T) { ` t.Run("stubs.source", func(t *testing.T) { - testJavaError(t, `stubs.source not available for api scope public`, bp+` - java_library { - name: "bar", - srcs: [":foo{.public.stubs.source}"], - java_resources: [ - ":foo{.public.api.txt}", - ":foo{.public.removed-api.txt}", - ], - } - `) + javaFixtureFactory. + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`stubs.source not available for api scope public`)). + RunTestWithBp(t, bp+` + java_library { + name: "bar", + srcs: [":foo{.public.stubs.source}"], + java_resources: [ + ":foo{.public.api.txt}", + ":foo{.public.removed-api.txt}", + ], + } + `) }) t.Run("api.txt", func(t *testing.T) { - testJavaError(t, `api.txt not available for api scope public`, bp+` - java_library { - name: "bar", - srcs: ["a.java"], - java_resources: [ - ":foo{.public.api.txt}", - ], - } - `) + javaFixtureFactory. + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`api.txt not available for api scope public`)). + RunTestWithBp(t, bp+` + java_library { + name: "bar", + srcs: ["a.java"], + java_resources: [ + ":foo{.public.api.txt}", + ], + } + `) }) t.Run("removed-api.txt", func(t *testing.T) { - testJavaError(t, `removed-api.txt not available for api scope public`, bp+` - java_library { - name: "bar", - srcs: ["a.java"], - java_resources: [ - ":foo{.public.removed-api.txt}", - ], - } - `) + javaFixtureFactory. + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`removed-api.txt not available for api scope public`)). + RunTestWithBp(t, bp+` + java_library { + name: "bar", + srcs: ["a.java"], + java_resources: [ + ":foo{.public.removed-api.txt}", + ], + } + `) }) } func TestJavaSdkLibrary_InvalidScopes(t *testing.T) { - testJavaError(t, `module "foo": enabled api scope "system" depends on disabled scope "public"`, ` - java_sdk_library { - name: "foo", - srcs: ["a.java", "b.java"], - api_packages: ["foo"], - // Explicitly disable public to test the check that ensures the set of enabled - // scopes is consistent. - public: { - enabled: false, - }, - system: { - enabled: true, - }, - } + javaFixtureFactory. + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo": enabled api scope "system" depends on disabled scope "public"`)). + RunTestWithBp(t, ` + java_sdk_library { + name: "foo", + srcs: ["a.java", "b.java"], + api_packages: ["foo"], + // Explicitly disable public to test the check that ensures the set of enabled + // scopes is consistent. + public: { + enabled: false, + }, + system: { + enabled: true, + }, + } `) } func TestJavaSdkLibrary_SdkVersion_ForScope(t *testing.T) { - testJava(t, ` + javaFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo"), + ).RunTestWithBp(t, ` java_sdk_library { name: "foo", srcs: ["a.java", "b.java"], @@ -2201,7 +2219,10 @@ func TestJavaSdkLibrary_SdkVersion_ForScope(t *testing.T) { } func TestJavaSdkLibrary_ModuleLib(t *testing.T) { - testJava(t, ` + javaFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo"), + ).RunTestWithBp(t, ` java_sdk_library { name: "foo", srcs: ["a.java", "b.java"], @@ -2217,7 +2238,10 @@ func TestJavaSdkLibrary_ModuleLib(t *testing.T) { } func TestJavaSdkLibrary_SystemServer(t *testing.T) { - testJava(t, ` + javaFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo"), + ).RunTestWithBp(t, ` java_sdk_library { name: "foo", srcs: ["a.java", "b.java"], @@ -2233,26 +2257,31 @@ func TestJavaSdkLibrary_SystemServer(t *testing.T) { } func TestJavaSdkLibrary_MissingScope(t *testing.T) { - testJavaError(t, `requires api scope module-lib from foo but it only has \[\] available`, ` - java_sdk_library { - name: "foo", - srcs: ["a.java"], - public: { - enabled: false, - }, - } + javaFixtureFactory. + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`requires api scope module-lib from foo but it only has \[\] available`)). + RunTestWithBp(t, ` + java_sdk_library { + name: "foo", + srcs: ["a.java"], + public: { + enabled: false, + }, + } - java_library { - name: "baz", - srcs: ["a.java"], - libs: ["foo"], - sdk_version: "module_current", - } + java_library { + name: "baz", + srcs: ["a.java"], + libs: ["foo"], + sdk_version: "module_current", + } `) } func TestJavaSdkLibrary_FallbackScope(t *testing.T) { - testJava(t, ` + javaFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo"), + ).RunTestWithBp(t, ` java_sdk_library { name: "foo", srcs: ["a.java"], @@ -2272,7 +2301,10 @@ func TestJavaSdkLibrary_FallbackScope(t *testing.T) { } func TestJavaSdkLibrary_DefaultToStubs(t *testing.T) { - ctx, _ := testJava(t, ` + result := javaFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo"), + ).RunTestWithBp(t, ` java_sdk_library { name: "foo", srcs: ["a.java"], @@ -2292,7 +2324,7 @@ func TestJavaSdkLibrary_DefaultToStubs(t *testing.T) { } `) // The baz library should depend on the system stubs jar. - bazLibrary := ctx.ModuleForTests("baz", "android_common").Rule("javac") + bazLibrary := result.ModuleForTests("baz", "android_common").Rule("javac") if expected, actual := `^-classpath .*:/[^:]*/turbine-combined/foo\.stubs.system\.jar$`, bazLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { t.Errorf("expected %q, found %#q", expected, actual) } @@ -2569,3 +2601,16 @@ func TestDataNativeBinaries(t *testing.T) { t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual) } } + +func TestDefaultInstallable(t *testing.T) { + ctx, _ := testJava(t, ` + java_test_host { + name: "foo" + } + `) + + buildOS := android.BuildOs.String() + module := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost) + assertDeepEquals(t, "Default installable value should be true.", proptools.BoolPtr(true), + module.properties.Installable) +} diff --git a/java/legacy_core_platform_api_usage.go b/java/legacy_core_platform_api_usage.go index cae9dc548..5949edd36 100644 --- a/java/legacy_core_platform_api_usage.go +++ b/java/legacy_core_platform_api_usage.go @@ -83,6 +83,7 @@ var legacyCorePlatformApiModules = []string{ "FrameworksNetTests", "FrameworksServicesRoboTests", "FrameworksServicesTests", + "FrameworksMockingServicesTests", "FrameworksUtilTests", "FrameworksWifiTests", "hid", diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go index 2c47b0a3a..4bfd4e2f9 100644 --- a/java/platform_compat_config.go +++ b/java/platform_compat_config.go @@ -20,11 +20,17 @@ import ( ) func init() { - android.RegisterSingletonType("platform_compat_config_singleton", platformCompatConfigSingletonFactory) - android.RegisterModuleType("platform_compat_config", PlatformCompatConfigFactory) - android.RegisterModuleType("global_compat_config", globalCompatConfigFactory) + registerPlatformCompatConfigBuildComponents(android.InitRegistrationContext) } +func registerPlatformCompatConfigBuildComponents(ctx android.RegistrationContext) { + ctx.RegisterSingletonType("platform_compat_config_singleton", platformCompatConfigSingletonFactory) + ctx.RegisterModuleType("platform_compat_config", PlatformCompatConfigFactory) + ctx.RegisterModuleType("global_compat_config", globalCompatConfigFactory) +} + +var PrepareForTestWithPlatformCompatConfig = android.FixtureRegisterWithContext(registerPlatformCompatConfigBuildComponents) + func platformCompatConfigPath(ctx android.PathContext) android.OutputPath { return android.PathForOutput(ctx, "compat_config", "merged_compat_config.xml") } @@ -146,7 +152,7 @@ func platformCompatConfigSingletonFactory() android.Singleton { func PlatformCompatConfigFactory() android.Module { module := &platformCompatConfig{} module.AddProperties(&module.properties) - android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) return module } diff --git a/java/proto.go b/java/proto.go index 652a4daec..8731822c3 100644 --- a/java/proto.go +++ b/java/proto.go @@ -94,7 +94,7 @@ func protoDeps(ctx android.BottomUpMutatorContext, p *android.ProtoProperties) { } } -func protoFlags(ctx android.ModuleContext, j *CompilerProperties, p *android.ProtoProperties, +func protoFlags(ctx android.ModuleContext, j *CommonProperties, p *android.ProtoProperties, flags javaBuilderFlags) javaBuilderFlags { flags.proto = android.GetProtoFlags(ctx, p) diff --git a/java/sdk_library.go b/java/sdk_library.go index b03f90cf4..e1ca77dcf 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1681,7 +1681,7 @@ func (s *defaultNamingScheme) apiModuleName(scope *apiScope, baseName string) st var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil) -func moduleStubLinkType(name string) (stub bool, ret linkType) { +func moduleStubLinkType(name string) (stub bool, ret sdkLinkType) { // This suffix-based approach is fragile and could potentially mis-trigger. // TODO(b/155164730): Clean this up when modules no longer reference sdk_lib stubs directly. if strings.HasSuffix(name, ".stubs.public") || strings.HasSuffix(name, "-stubs-publicapi") { |