diff options
Diffstat (limited to 'java')
| -rw-r--r-- | java/aar.go | 17 | ||||
| -rw-r--r-- | java/android_manifest.go | 5 | ||||
| -rwxr-xr-x | java/app.go | 23 | ||||
| -rw-r--r-- | java/app_test.go | 62 | ||||
| -rw-r--r-- | java/dexpreopt.go | 38 | ||||
| -rw-r--r-- | java/dexpreopt_bootjars.go | 25 | ||||
| -rw-r--r-- | java/dexpreopt_bootjars_test.go | 2 | ||||
| -rw-r--r-- | java/dexpreopt_config.go | 93 | ||||
| -rw-r--r-- | java/droiddoc.go | 7 | ||||
| -rw-r--r-- | java/java.go | 86 | ||||
| -rw-r--r-- | java/java_test.go | 22 | ||||
| -rw-r--r-- | java/sdk.go | 26 | ||||
| -rw-r--r-- | java/sdk_library.go | 4 | ||||
| -rw-r--r-- | java/sdk_test.go | 9 | ||||
| -rw-r--r-- | java/testing.go | 1 |
15 files changed, 261 insertions, 159 deletions
diff --git a/java/aar.go b/java/aar.go index 24c5e7d04..6e3b9e6d3 100644 --- a/java/aar.go +++ b/java/aar.go @@ -101,6 +101,7 @@ type aapt struct { usesNonSdkApis bool sdkLibraries []string hasNoCode bool + LoggingParent string splitNames []string splits []split @@ -134,15 +135,8 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext, manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths, resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) { - hasVersionCode := false - hasVersionName := false - for _, f := range a.aaptProperties.Aaptflags { - if strings.HasPrefix(f, "--version-code") { - hasVersionCode = true - } else if strings.HasPrefix(f, "--version-name") { - hasVersionName = true - } - } + hasVersionCode := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-code") + hasVersionName := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-name") // Flags specified in Android.bp linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...) @@ -241,7 +235,8 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile) manifestPath := manifestFixer(ctx, manifestSrcPath, sdkContext, sdkLibraries, - a.isLibrary, a.useEmbeddedNativeLibs, a.usesNonSdkApis, a.useEmbeddedDex, a.hasNoCode) + a.isLibrary, a.useEmbeddedNativeLibs, a.usesNonSdkApis, a.useEmbeddedDex, a.hasNoCode, + a.LoggingParent) // Add additional manifest files to transitive manifests. additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests) @@ -337,7 +332,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex // Extract assets from the resource package output so that they can be used later in aapt2link // for modules that depend on this one. - if android.PrefixedStringInList(linkFlags, "-A ") || len(assetPackages) > 0 { + if android.PrefixInList(linkFlags, "-A ") || len(assetPackages) > 0 { assets := android.PathForModuleOut(ctx, "assets.zip") ctx.Build(pctx, android.BuildParams{ Rule: extractAssetsRule, diff --git a/java/android_manifest.go b/java/android_manifest.go index e3646f5f9..9a71be28a 100644 --- a/java/android_manifest.go +++ b/java/android_manifest.go @@ -53,7 +53,7 @@ var optionalUsesLibs = []string{ // Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext sdkContext, sdkLibraries []string, - isLibrary, useEmbeddedNativeLibs, usesNonSdkApis, useEmbeddedDex, hasNoCode bool) android.Path { + isLibrary, useEmbeddedNativeLibs, usesNonSdkApis, useEmbeddedDex, hasNoCode bool, loggingParent string) android.Path { var args []string if isLibrary { @@ -91,6 +91,9 @@ func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext args = append(args, "--has-no-code") } + if loggingParent != "" { + args = append(args, "--logging-parent", loggingParent) + } var deps android.Paths targetSdkVersion, err := sdkContext.targetSdkVersion().effectiveVersionString(ctx) if err != nil { diff --git a/java/app.go b/java/app.go index 9503ec455..71bad683c 100755 --- a/java/app.go +++ b/java/app.go @@ -111,6 +111,9 @@ type overridableAppProperties struct { // the package name of this app. The package name in the manifest file is used if one was not given. Package_name *string + + // the logging parent of this app. + Logging_parent *string } type AndroidApp struct { @@ -142,6 +145,10 @@ type AndroidApp struct { noticeOutputs android.NoticeOutputs } +func (a *AndroidApp) IsInstallable() bool { + return Bool(a.properties.Installable) +} + func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths { return nil } @@ -269,13 +276,7 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) { aaptLinkFlags := []string{} // Add TARGET_AAPT_CHARACTERISTICS values to AAPT link flags if they exist and --product flags were not provided. - hasProduct := false - for _, f := range a.aaptProperties.Aaptflags { - if strings.HasPrefix(f, "--product") { - hasProduct = true - break - } - } + hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product") if !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 { aaptLinkFlags = append(aaptLinkFlags, "--product", ctx.Config().ProductAAPTCharacteristics()) } @@ -305,7 +306,7 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) { a.aapt.splitNames = a.appProperties.Package_splits a.aapt.sdkLibraries = a.exportedSdkLibs - + a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent) a.aapt.buildActions(ctx, sdkContext(a), aaptLinkFlags...) // apps manifests are handled by aapt, don't let Module see them @@ -338,7 +339,6 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path { installDir = filepath.Join("app", a.installApkName) } a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk") - a.dexpreopter.isInstallable = Bool(a.properties.Installable) a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx) a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries() @@ -922,6 +922,10 @@ type AndroidAppImportProperties struct { Filename *string } +func (a *AndroidAppImport) IsInstallable() bool { + return true +} + // Updates properties with variant-specific values. func (a *AndroidAppImport) processVariants(ctx android.LoadHookContext) { config := ctx.Config() @@ -1064,7 +1068,6 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext } a.dexpreopter.installPath = installDir.Join(ctx, a.BaseModuleName()+".apk") - a.dexpreopter.isInstallable = true a.dexpreopter.isPresignedPrebuilt = Bool(a.properties.Presigned) a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx) diff --git a/java/app_test.go b/java/app_test.go index c86b038af..6d94160fa 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -1181,6 +1181,7 @@ func TestOverrideAndroidApp(t *testing.T) { name: "bar", base: "foo", certificate: ":new_certificate", + logging_parent: "bah", } android_app_certificate { @@ -1196,37 +1197,41 @@ func TestOverrideAndroidApp(t *testing.T) { `) expectedVariants := []struct { - moduleName string - variantName string - apkName string - apkPath string - signFlag string - overrides []string - aaptFlag string + moduleName string + variantName string + apkName string + apkPath string + signFlag string + overrides []string + aaptFlag string + logging_parent string }{ { - moduleName: "foo", - variantName: "android_common", - apkPath: "/target/product/test_device/system/app/foo/foo.apk", - signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", - overrides: []string{"qux"}, - aaptFlag: "", + moduleName: "foo", + variantName: "android_common", + apkPath: "/target/product/test_device/system/app/foo/foo.apk", + signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", + overrides: []string{"qux"}, + aaptFlag: "", + logging_parent: "", }, { - moduleName: "bar", - variantName: "android_common_bar", - apkPath: "/target/product/test_device/system/app/bar/bar.apk", - signFlag: "cert/new_cert.x509.pem cert/new_cert.pk8", - overrides: []string{"qux", "foo"}, - aaptFlag: "", + moduleName: "bar", + variantName: "android_common_bar", + apkPath: "/target/product/test_device/system/app/bar/bar.apk", + signFlag: "cert/new_cert.x509.pem cert/new_cert.pk8", + overrides: []string{"qux", "foo"}, + aaptFlag: "", + logging_parent: "bah", }, { - moduleName: "baz", - variantName: "android_common_baz", - apkPath: "/target/product/test_device/system/app/baz/baz.apk", - signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", - overrides: []string{"qux", "foo"}, - aaptFlag: "--rename-manifest-package org.dandroid.bp", + moduleName: "baz", + variantName: "android_common_baz", + apkPath: "/target/product/test_device/system/app/baz/baz.apk", + signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", + overrides: []string{"qux", "foo"}, + aaptFlag: "--rename-manifest-package org.dandroid.bp", + logging_parent: "", }, } for _, expected := range expectedVariants { @@ -1260,6 +1265,13 @@ func TestOverrideAndroidApp(t *testing.T) { expected.overrides, mod.appProperties.Overrides) } + // Test Overridable property: Logging_parent + logging_parent := mod.aapt.LoggingParent + if expected.logging_parent != logging_parent { + t.Errorf("Incorrect overrides property value for logging parent, expected: %q, got: %q", + expected.logging_parent, logging_parent) + } + // Check the package renaming flag, if exists. res := variant.Output("package-res.apk") aapt2Flags := res.Args["flags"] diff --git a/java/dexpreopt.go b/java/dexpreopt.go index c81e199c6..4313964aa 100644 --- a/java/dexpreopt.go +++ b/java/dexpreopt.go @@ -19,6 +19,11 @@ import ( "android/soong/dexpreopt" ) +type dexpreopterInterface interface { + IsInstallable() bool // Structs that embed dexpreopter must implement this. + dexpreoptDisabled(ctx android.BaseModuleContext) bool +} + type dexpreopter struct { dexpreoptProperties DexpreoptProperties @@ -26,7 +31,6 @@ type dexpreopter struct { uncompressedDex bool isSDKLibrary bool isTest bool - isInstallable bool isPresignedPrebuilt bool manifestFile android.Path @@ -58,8 +62,8 @@ type DexpreoptProperties struct { } } -func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool { - global := dexpreoptGlobalConfig(ctx) +func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool { + global := dexpreopt.GetGlobalConfig(ctx) if global.DisablePreopt { return true @@ -81,7 +85,11 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool { return true } - if !d.isInstallable { + if !ctx.Module().(dexpreopterInterface).IsInstallable() { + return true + } + + if ctx.Host() { return true } @@ -95,16 +103,28 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool { return false } +func dexpreoptToolDepsMutator(ctx android.BottomUpMutatorContext) { + if d, ok := ctx.Module().(dexpreopterInterface); !ok || d.dexpreoptDisabled(ctx) { + return + } + dexpreopt.RegisterToolDeps(ctx) +} + func odexOnSystemOther(ctx android.ModuleContext, installPath android.InstallPath) bool { - return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreoptGlobalConfig(ctx)) + return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreopt.GetGlobalConfig(ctx)) } func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.ModuleOutPath) android.ModuleOutPath { - if d.dexpreoptDisabled(ctx) { + // TODO(b/148690468): The check on d.installPath is to bail out in cases where + // the dexpreopter struct hasn't been fully initialized before we're called, + // e.g. in aar.go. This keeps the behaviour that dexpreopting is effectively + // disabled, even if installable is true. + if d.dexpreoptDisabled(ctx) || d.installPath.Base() == "." { return dexJarFile } - global := dexpreoptGlobalConfig(ctx) + globalSoong := dexpreopt.GetGlobalSoongConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) bootImage := defaultBootImageConfig(ctx) dexFiles := bootImage.dexPathsDeps.Paths() dexLocations := bootImage.dexLocationsDeps @@ -156,7 +176,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo } } - dexpreoptConfig := dexpreopt.ModuleConfig{ + dexpreoptConfig := &dexpreopt.ModuleConfig{ Name: ctx.ModuleName(), DexLocation: dexLocation, BuildPath: android.PathForModuleOut(ctx, "dexpreopt", ctx.ModuleName()+".jar").OutputPath, @@ -191,7 +211,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo PresignedPrebuilt: d.isPresignedPrebuilt, } - dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, global, dexpreoptConfig) + dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, globalSoong, global, dexpreoptConfig) if err != nil { ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error()) return dexJarFile diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 607a43781..655a47644 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -165,7 +165,7 @@ func dexpreoptBootJarsFactory() android.Singleton { } func skipDexpreoptBootJars(ctx android.PathContext) bool { - if dexpreoptGlobalConfig(ctx).DisablePreopt { + if dexpreopt.GetGlobalConfig(ctx).DisablePreopt { return true } @@ -205,11 +205,15 @@ func (d *dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) { if skipDexpreoptBootJars(ctx) { return } + if dexpreopt.GetCachedGlobalSoongConfig(ctx) == nil { + // No module has enabled dexpreopting, so we assume there will be no boot image to make. + return + } d.dexpreoptConfigForMake = android.PathForOutput(ctx, ctx.Config().DeviceName(), "dexpreopt.config") writeGlobalConfigForMake(ctx, d.dexpreoptConfigForMake) - global := dexpreoptGlobalConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) // Skip recompiling the boot image for the second sanitization phase. We'll get separate paths // and invalidate first-stage artifacts which are crucial to SANITIZE_LITE builds. @@ -295,7 +299,8 @@ func buildBootImage(ctx android.SingletonContext, config bootImageConfig) *bootI func buildBootImageRuleForArch(ctx android.SingletonContext, image *bootImage, arch android.ArchType, profile android.Path, missingDeps []string) android.WritablePaths { - global := dexpreoptGlobalConfig(ctx) + globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) symbolsDir := image.symbolsDir.Join(ctx, image.installSubdir, arch.String()) symbolsFile := symbolsDir.Join(ctx, image.stem+".oat") @@ -330,7 +335,7 @@ func buildBootImageRuleForArch(ctx android.SingletonContext, image *bootImage, invocationPath := outputPath.ReplaceExtension(ctx, "invocation") - cmd.Tool(global.SoongConfig.Dex2oat). + cmd.Tool(globalSoong.Dex2oat). Flag("--avoid-storing-invocation"). FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath). Flag("--runtime-arg").FlagWithArg("-Xms", global.Dex2oatImageXms). @@ -433,7 +438,8 @@ It is likely that the boot classpath is inconsistent. Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.` func bootImageProfileRule(ctx android.SingletonContext, image *bootImage, missingDeps []string) android.WritablePath { - global := dexpreoptGlobalConfig(ctx) + globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) if global.DisableGenerateProfile || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() { return nil @@ -464,7 +470,7 @@ func bootImageProfileRule(ctx android.SingletonContext, image *bootImage, missin rule.Command(). Text(`ANDROID_LOG_TAGS="*:e"`). - Tool(global.SoongConfig.Profman). + Tool(globalSoong.Profman). FlagWithInput("--create-profile-from=", bootImageProfile). FlagForEachInput("--apk=", image.dexPathsDeps.Paths()). FlagForEachArg("--dex-location=", image.dexLocationsDeps). @@ -487,7 +493,8 @@ func bootImageProfileRule(ctx android.SingletonContext, image *bootImage, missin var bootImageProfileRuleKey = android.NewOnceKey("bootImageProfileRule") func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImage, missingDeps []string) android.WritablePath { - global := dexpreoptGlobalConfig(ctx) + globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) if global.DisableGenerateProfile || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() { return nil @@ -513,7 +520,7 @@ func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImage, mi rule.Command(). Text(`ANDROID_LOG_TAGS="*:e"`). - Tool(global.SoongConfig.Profman). + Tool(globalSoong.Profman). Flag("--generate-boot-profile"). FlagWithInput("--create-profile-from=", bootFrameworkProfile). FlagForEachInput("--apk=", image.dexPathsDeps.Paths()). @@ -575,7 +582,7 @@ func dumpOatRules(ctx android.SingletonContext, image *bootImage) { } func writeGlobalConfigForMake(ctx android.SingletonContext, path android.WritablePath) { - data := dexpreoptGlobalConfigRaw(ctx).data + data := dexpreopt.GetGlobalConfigRawData(ctx) ctx.Build(pctx, android.BuildParams{ Rule: android.WriteFile, diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go index 4ce30f678..c3b2133a9 100644 --- a/java/dexpreopt_bootjars_test.go +++ b/java/dexpreopt_bootjars_test.go @@ -49,7 +49,7 @@ func TestDexpreoptBootJars(t *testing.T) { pathCtx := android.PathContextForTesting(config) dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx) dexpreoptConfig.BootJars = []string{"foo", "bar", "baz"} - setDexpreoptTestGlobalConfig(config, dexpreoptConfig) + dexpreopt.SetTestGlobalConfig(config, dexpreoptConfig) ctx := testContext() diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go index 4c9add8b5..28f56d24a 100644 --- a/java/dexpreopt_config.go +++ b/java/dexpreopt_config.go @@ -15,6 +15,7 @@ package java import ( + "fmt" "path/filepath" "strings" @@ -22,67 +23,36 @@ import ( "android/soong/dexpreopt" ) -// dexpreoptGlobalConfig returns the global dexpreopt.config. It is loaded once the first time it is called for any -// ctx.Config(), and returns the same data for all future calls with the same ctx.Config(). A value can be inserted -// for tests using setDexpreoptTestGlobalConfig. -func dexpreoptGlobalConfig(ctx android.PathContext) dexpreopt.GlobalConfig { - return dexpreoptGlobalConfigRaw(ctx).global -} - -type globalConfigAndRaw struct { - global dexpreopt.GlobalConfig - data []byte -} - -func dexpreoptGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw { - return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} { - if data, err := ctx.Config().DexpreoptGlobalConfig(ctx); err != nil { - panic(err) - } else if data != nil { - soongConfig := dexpreopt.CreateGlobalSoongConfig(ctx) - globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, data, soongConfig) - if err != nil { - panic(err) - } - return globalConfigAndRaw{globalConfig, data} - } - - // No global config filename set, see if there is a test config set - return ctx.Config().Once(dexpreoptTestGlobalConfigKey, func() interface{} { - // Nope, return a config with preopting disabled - return globalConfigAndRaw{dexpreopt.GlobalConfig{ - DisablePreopt: true, - DisableGenerateProfile: true, - }, nil} - }) - }).(globalConfigAndRaw) -} - -// setDexpreoptTestGlobalConfig sets a GlobalConfig that future calls to dexpreoptGlobalConfig will return. It must -// be called before the first call to dexpreoptGlobalConfig for the config. -func setDexpreoptTestGlobalConfig(config android.Config, globalConfig dexpreopt.GlobalConfig) { - config.Once(dexpreoptTestGlobalConfigKey, func() interface{} { return globalConfigAndRaw{globalConfig, nil} }) -} - -var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig") -var dexpreoptTestGlobalConfigKey = android.NewOnceKey("TestDexpreoptGlobalConfig") - // systemServerClasspath returns the on-device locations of the modules in the system server classpath. It is computed // once the first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same // ctx.Config(). -func systemServerClasspath(ctx android.PathContext) []string { +func systemServerClasspath(ctx android.MakeVarsContext) []string { return ctx.Config().OnceStringSlice(systemServerClasspathKey, func() []string { - global := dexpreoptGlobalConfig(ctx) - + global := dexpreopt.GetGlobalConfig(ctx) var systemServerClasspathLocations []string - for _, m := range global.SystemServerJars { + var dexpreoptJars = *DexpreoptedSystemServerJars(ctx.Config()) + // 1) The jars that are dexpreopted. + for _, m := range dexpreoptJars { systemServerClasspathLocations = append(systemServerClasspathLocations, filepath.Join("/system/framework", m+".jar")) } + // 2) The jars that are from an updatable apex. for _, m := range global.UpdatableSystemServerJars { systemServerClasspathLocations = append(systemServerClasspathLocations, dexpreopt.GetJarLocationFromApexJarPair(m)) } + // 3) The jars from make (which are not updatable, not preopted). + for _, m := range dexpreopt.NonUpdatableSystemServerJars(ctx, global) { + if !android.InList(m, dexpreoptJars) { + systemServerClasspathLocations = append(systemServerClasspathLocations, + filepath.Join("/system/framework", m+".jar")) + } + } + if len(systemServerClasspathLocations) != len(global.SystemServerJars)+len(global.UpdatableSystemServerJars) { + panic(fmt.Errorf("Wrong number of system server jars, got %d, expected %d", + len(systemServerClasspathLocations), + len(global.SystemServerJars)+len(global.UpdatableSystemServerJars))) + } return systemServerClasspathLocations }) } @@ -112,26 +82,17 @@ func stemOf(moduleName string) string { return moduleName } -func getJarsFromApexJarPairs(apexJarPairs []string) []string { - modules := make([]string, len(apexJarPairs)) - for i, p := range apexJarPairs { - _, jar := dexpreopt.SplitApexJarPair(p) - modules[i] = jar - } - return modules -} - var ( - bootImageConfigKey = android.NewOnceKey("bootImageConfig") - artBootImageName = "art" - frameworkBootImageName = "boot" + bootImageConfigKey = android.NewOnceKey("bootImageConfig") + artBootImageName = "art" + frameworkBootImageName = "boot" ) // Construct the global boot image configs. func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig { return ctx.Config().Once(bootImageConfigKey, func() interface{} { - global := dexpreoptGlobalConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) targets := dexpreoptTargets(ctx) deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName()) @@ -141,7 +102,7 @@ func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig { artModules = append(artModules, "jacocoagent") } frameworkModules := android.RemoveListFromList(global.BootJars, - concat(artModules, getJarsFromApexJarPairs(global.UpdatableBootJars))) + concat(artModules, dexpreopt.GetJarsFromApexJarPairs(global.UpdatableBootJars))) artSubdir := "apex/com.android.art/javalib" frameworkSubdir := "system/framework" @@ -179,8 +140,8 @@ func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig { } configs := map[string]*bootImageConfig{ - artBootImageName: &artCfg, - frameworkBootImageName: &frameworkCfg, + artBootImageName: &artCfg, + frameworkBootImageName: &frameworkCfg, } // common to all configs @@ -237,7 +198,7 @@ func defaultBootImageConfig(ctx android.PathContext) bootImageConfig { func defaultBootclasspath(ctx android.PathContext) []string { return ctx.Config().OnceStringSlice(defaultBootclasspathKey, func() []string { - global := dexpreoptGlobalConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) image := defaultBootImageConfig(ctx) updatableBootclasspath := make([]string, len(global.UpdatableBootJars)) diff --git a/java/droiddoc.go b/java/droiddoc.go index 959f1c734..6b393144f 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -605,11 +605,8 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { continue } packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".") - for _, pkg := range filterPackages { - if strings.HasPrefix(packageName, pkg) { - filtered = append(filtered, src) - break - } + if android.HasAnyPrefix(packageName, filterPackages) { + filtered = append(filtered, src) } } return filtered diff --git a/java/java.go b/java/java.go index dd44d06aa..c3e2c9656 100644 --- a/java/java.go +++ b/java/java.go @@ -23,12 +23,14 @@ import ( "path/filepath" "strconv" "strings" + "sync" "github.com/google/blueprint" "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/dexpreopt" "android/soong/java/config" "android/soong/tradefed" ) @@ -52,6 +54,8 @@ func init() { PropertyName: "java_tests", }, }) + + android.PostDepsMutators(RegisterPostDepsMutators) } func RegisterJavaBuildComponents(ctx android.RegistrationContext) { @@ -72,10 +76,52 @@ func RegisterJavaBuildComponents(ctx android.RegistrationContext) { 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 RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { + ctx.BottomUp("ordered_system_server_jars", systemServerJarsDepsMutator) +} + +var ( + dexpreoptedSystemServerJarsKey = android.NewOnceKey("dexpreoptedSystemServerJars") + dexpreoptedSystemServerJarsLock sync.Mutex +) + +func DexpreoptedSystemServerJars(config android.Config) *[]string { + return config.Once(dexpreoptedSystemServerJarsKey, func() interface{} { + return &[]string{} + }).(*[]string) +} + +// A PostDepsMutator pass that enforces total order on non-updatable system server jars. A total +// order is neededed because such jars must be dexpreopted together (each jar on the list must have +// all preceding jars in its class loader context). The total order must be compatible with the +// partial order imposed by genuine dependencies between system server jars (which is not always +// respected by the PRODUCT_SYSTEM_SERVER_JARS variable). +// +// An earlier mutator pass creates genuine dependencies, and this pass traverses the jars in that +// order (which is partial and non-deterministic). This pass adds additional dependencies between +// jars, making the order total and deterministic. It also constructs a global ordered list. +func systemServerJarsDepsMutator(ctx android.BottomUpMutatorContext) { + jars := dexpreopt.NonUpdatableSystemServerJars(ctx, dexpreopt.GetGlobalConfig(ctx)) + name := ctx.ModuleName() + if android.InList(name, jars) { + dexpreoptedSystemServerJarsLock.Lock() + defer dexpreoptedSystemServerJarsLock.Unlock() + jars := DexpreoptedSystemServerJars(ctx.Config()) + for _, dep := range *jars { + ctx.AddDependency(ctx.Module(), dexpreopt.SystemServerDepTag, dep) + } + *jars = append(*jars, name) + } +} + func (j *Module) checkSdkVersion(ctx android.ModuleContext) { if j.SocSpecific() || j.DeviceSpecific() || (j.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) { @@ -659,6 +705,11 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { } else if j.shouldInstrumentStatic(ctx) { ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent") } + + // services depend on com.android.location.provider, but dependency in not registered in a Blueprint file + if ctx.ModuleName() == "services" { + ctx.AddDependency(ctx.Module(), dexpreopt.SystemServerForcedDepTag, "com.android.location.provider") + } } func hasSrcExt(srcs []string, ext string) bool { @@ -756,6 +807,7 @@ const ( javaSdk javaSystem javaModule + javaSystemServer javaPlatform ) @@ -789,6 +841,10 @@ func (m *Module) getLinkType(name string) (ret linkType, stubs bool) { return javaModule, true case ver.kind == sdkModule: return javaModule, false + case name == "services-stubs": + return javaSystemServer, true + case ver.kind == sdkSystemServer: + return javaSystemServer, false case ver.kind == sdkPrivate || ver.kind == sdkNone || ver.kind == sdkCorePlatform: return javaPlatform, false case !ver.valid(): @@ -824,17 +880,23 @@ func checkLinkType(ctx android.ModuleContext, from *Module, to linkTypeContext, } break case javaSystem: - if otherLinkType == javaPlatform || otherLinkType == javaModule { + if otherLinkType == javaPlatform || otherLinkType == javaModule || otherLinkType == javaSystemServer { ctx.ModuleErrorf("compiles against system API, but dependency %q is compiling against private API."+commonMessage, ctx.OtherModuleName(to)) } break case javaModule: - if otherLinkType == javaPlatform { + if otherLinkType == javaPlatform || otherLinkType == javaSystemServer { ctx.ModuleErrorf("compiles against module API, but dependency %q is compiling against private API."+commonMessage, ctx.OtherModuleName(to)) } break + case javaSystemServer: + if otherLinkType == javaPlatform { + ctx.ModuleErrorf("compiles against system server API, but dependency %q is compiling against private API."+commonMessage, + ctx.OtherModuleName(to)) + } + break case javaPlatform: // no restriction on link-type break @@ -1475,6 +1537,16 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { j.implementationAndResourcesJar = implementationAndResourcesJar + // Enable dex compilation for the APEX variants, unless it is disabled explicitly + if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !j.IsForPlatform() { + if j.deviceProperties.Compile_dex == nil { + j.deviceProperties.Compile_dex = proptools.BoolPtr(true) + } + if j.deviceProperties.Hostdex == nil { + j.deviceProperties.Hostdex = proptools.BoolPtr(true) + } + } + if ctx.Device() && j.hasCode(ctx) && (Bool(j.properties.Installable) || Bool(j.deviceProperties.Compile_dex)) { // Dex compilation @@ -1724,6 +1796,10 @@ func (j *Module) JacocoReportClassesFile() android.Path { return j.jacocoReportClassesFile } +func (j *Module) IsInstallable() bool { + return Bool(j.properties.Installable) +} + // // Java libraries (.jar file) // @@ -1761,7 +1837,6 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.checkSdkVersion(ctx) j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary - j.dexpreopter.isInstallable = Bool(j.properties.Installable) j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter) j.deviceProperties.UncompressDex = j.dexpreopter.uncompressedDex j.compile(ctx, nil) @@ -2518,13 +2593,16 @@ func (j *DexImport) Stem() string { return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name()) } +func (j *DexImport) IsInstallable() bool { + return true +} + func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { if len(j.properties.Jars) != 1 { ctx.PropertyErrorf("jars", "exactly one jar must be provided") } j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") - j.dexpreopter.isInstallable = true j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter) inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars") diff --git a/java/java_test.go b/java/java_test.go index 8815c09db..a2226b59e 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -57,7 +57,15 @@ func TestMain(m *testing.M) { } func testConfig(env map[string]string, bp string, fs map[string][]byte) android.Config { - return TestConfig(buildDir, env, bp, fs) + bp += dexpreopt.BpToolModulesForTest() + + config := TestConfig(buildDir, env, bp, fs) + + // Set up the global Once cache used for dexpreopt.GlobalSoongConfig, so that + // it doesn't create a real one, which would fail. + _ = dexpreopt.GlobalSoongConfigForTests(config) + + return config } func testContext() *android.TestContext { @@ -86,6 +94,8 @@ func testContext() *android.TestContext { cc.RegisterRequiredBuildComponentsForTest(ctx) ctx.RegisterModuleType("ndk_prebuilt_shared_stl", cc.NdkPrebuiltSharedStlFactory) + dexpreopt.RegisterToolModulesForTest(ctx) + return ctx } @@ -93,7 +103,7 @@ func run(t *testing.T, ctx *android.TestContext, config android.Config) { t.Helper() pathCtx := android.PathContextForTesting(config) - setDexpreoptTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx)) + dexpreopt.SetTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx)) ctx.Register(config) _, errs := ctx.ParseBlueprintsFiles("Android.bp") @@ -112,7 +122,7 @@ func testJavaErrorWithConfig(t *testing.T, pattern string, config android.Config ctx := testContext() pathCtx := android.PathContextForTesting(config) - setDexpreoptTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx)) + dexpreopt.SetTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx)) ctx.Register(config) _, errs := ctx.ParseBlueprintsFiles("Android.bp") @@ -1112,9 +1122,9 @@ func TestJavaSdkLibrary(t *testing.T) { ctx.ModuleForTests("foo"+sdkStubsLibrarySuffix, "android_common") ctx.ModuleForTests("foo"+sdkStubsLibrarySuffix+sdkSystemApiSuffix, "android_common") ctx.ModuleForTests("foo"+sdkStubsLibrarySuffix+sdkTestApiSuffix, "android_common") - ctx.ModuleForTests("foo"+sdkDocsSuffix, "android_common") - ctx.ModuleForTests("foo"+sdkDocsSuffix+sdkSystemApiSuffix, "android_common") - ctx.ModuleForTests("foo"+sdkDocsSuffix+sdkTestApiSuffix, "android_common") + ctx.ModuleForTests("foo"+sdkStubsSourceSuffix, "android_common") + ctx.ModuleForTests("foo"+sdkStubsSourceSuffix+sdkSystemApiSuffix, "android_common") + ctx.ModuleForTests("foo"+sdkStubsSourceSuffix+sdkTestApiSuffix, "android_common") ctx.ModuleForTests("foo"+sdkXmlFileSuffix, "android_arm64_armv8-a") ctx.ModuleForTests("foo.api.public.28", "") ctx.ModuleForTests("foo.api.system.28", "") diff --git a/java/sdk.go b/java/sdk.go index 1c047a353..1e60d6774 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -72,6 +72,7 @@ const ( sdkSystem sdkTest sdkModule + sdkSystemServer sdkPrivate ) @@ -94,6 +95,8 @@ func (k sdkKind) String() string { return "core_platform" case sdkModule: return "module" + case sdkSystemServer: + return "system_server" default: return "invalid" } @@ -261,6 +264,8 @@ func sdkSpecFrom(str string) sdkSpec { kind = sdkTest case "module": kind = sdkModule + case "system_server": + kind = sdkSystemServer default: return sdkSpec{sdkInvalid, sdkVersionNone, str} } @@ -324,13 +329,13 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext sdkContext) sdkDep } } - toModule := func(m, r string, aidl android.Path) sdkDep { + toModule := func(modules []string, res string, aidl android.Path) sdkDep { return sdkDep{ useModule: true, - bootclasspath: []string{m, config.DefaultLambdaStubsLibrary}, + bootclasspath: append(modules, config.DefaultLambdaStubsLibrary), systemModules: "core-current-stubs-system-modules", - java9Classpath: []string{m}, - frameworkResModule: r, + java9Classpath: modules, + frameworkResModule: res, aidl: android.OptionalPathForPath(aidl), } } @@ -380,16 +385,19 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext sdkContext) sdkDep noFrameworksLibs: true, } case sdkPublic: - return toModule("android_stubs_current", "framework-res", sdkFrameworkAidlPath(ctx)) + return toModule([]string{"android_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx)) case sdkSystem: - return toModule("android_system_stubs_current", "framework-res", sdkFrameworkAidlPath(ctx)) + return toModule([]string{"android_system_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx)) case sdkTest: - return toModule("android_test_stubs_current", "framework-res", sdkFrameworkAidlPath(ctx)) + return toModule([]string{"android_test_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx)) case sdkCore: - return toModule("core.current.stubs", "", nil) + return toModule([]string{"core.current.stubs"}, "", nil) case sdkModule: // TODO(146757305): provide .apk and .aidl that have more APIs for modules - return toModule("android_module_lib_stubs_current", "framework-res", sdkFrameworkAidlPath(ctx)) + return toModule([]string{"android_module_lib_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx)) + case sdkSystemServer: + // TODO(146757305): provide .apk and .aidl that have more APIs for modules + return toModule([]string{"android_module_lib_stubs_current", "services-stubs"}, "framework-res", sdkFrameworkAidlPath(ctx)) default: panic(fmt.Errorf("invalid sdk %q", sdkVersion.raw)) } diff --git a/java/sdk_library.go b/java/sdk_library.go index 3c376d079..4f4029aa3 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -34,7 +34,7 @@ const ( sdkStubsLibrarySuffix = ".stubs" sdkSystemApiSuffix = ".system" sdkTestApiSuffix = ".test" - sdkDocsSuffix = ".docs" + sdkStubsSourceSuffix = ".stubs.source" sdkXmlFileSuffix = ".xml" permissionsTemplate = `<?xml version="1.0" encoding="utf-8"?>\n` + `<!-- Copyright (C) 2018 The Android Open Source Project\n` + @@ -109,7 +109,7 @@ func (scope *apiScope) stubsModuleName(baseName string) string { } func (scope *apiScope) docsModuleName(baseName string) string { - return baseName + sdkDocsSuffix + scope.moduleSuffix + return baseName + sdkStubsSourceSuffix + scope.moduleSuffix } type apiScopes []*apiScope diff --git a/java/sdk_test.go b/java/sdk_test.go index c815fe3c1..ea6733d86 100644 --- a/java/sdk_test.go +++ b/java/sdk_test.go @@ -212,7 +212,6 @@ func TestClasspath(t *testing.T) { aidl: "-pprebuilts/sdk/29/public/framework.aidl", }, { - name: "module_current", properties: `sdk_version: "module_current",`, bootclasspath: []string{"android_module_lib_stubs_current", "core-lambda-stubs"}, @@ -220,6 +219,14 @@ func TestClasspath(t *testing.T) { java9classpath: []string{"android_module_lib_stubs_current"}, aidl: "-p" + buildDir + "/framework.aidl", }, + { + name: "system_server_current", + properties: `sdk_version: "system_server_current",`, + bootclasspath: []string{"android_module_lib_stubs_current", "services-stubs", "core-lambda-stubs"}, + system: "core-current-stubs-system-modules", + java9classpath: []string{"android_module_lib_stubs_current", "services-stubs"}, + aidl: "-p" + buildDir + "/framework.aidl", + }, } for _, testcase := range classpathTestcases { diff --git a/java/testing.go b/java/testing.go index 8f979c73e..3111109a5 100644 --- a/java/testing.go +++ b/java/testing.go @@ -147,6 +147,7 @@ func GatherRequiredDepsForTest() string { "android_system_stubs_current", "android_test_stubs_current", "android_module_lib_stubs_current", + "services-stubs", "core.current.stubs", "core.platform.api.stubs", "kotlin-stdlib", |