Merge changes I55a5a295,I9c09451d,I05177388

* changes:
  Use the profiles in the APEX to dexpreopt system server jars.
  Add tests for the ignored "profile_guided: true" property.
  Output dex_preopt to SDK snapshot.
This commit is contained in:
Treehugger Robot
2023-02-16 14:46:19 +00:00
committed by Gerrit Code Review
7 changed files with 264 additions and 32 deletions

View File

@@ -1769,7 +1769,7 @@ func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaMod
func apexFileForJavaModuleProfile(ctx android.BaseModuleContext, module javaModule) *apexFile { func apexFileForJavaModuleProfile(ctx android.BaseModuleContext, module javaModule) *apexFile {
if dexpreopter, ok := module.(java.DexpreopterInterface); ok { if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
if profilePathOnHost := dexpreopter.ProfilePathOnHost(); profilePathOnHost != nil { if profilePathOnHost := dexpreopter.OutputProfilePathOnHost(); profilePathOnHost != nil {
dirInApex := "javalib" dirInApex := "javalib"
af := newApexFile(ctx, profilePathOnHost, module.BaseModuleName()+"-profile", dirInApex, etc, nil) af := newApexFile(ctx, profilePathOnHost, module.BaseModuleName()+"-profile", dirInApex, etc, nil)
af.customStem = module.Stem() + ".jar.prof" af.customStem = module.Stem() + ".jar.prof"

View File

@@ -15,10 +15,11 @@
package apex package apex
import ( import (
"android/soong/dexpreopt" "strings"
"testing" "testing"
"android/soong/android" "android/soong/android"
"android/soong/dexpreopt"
"android/soong/java" "android/soong/java"
) )
@@ -31,7 +32,7 @@ func TestSystemserverclasspathFragmentContents(t *testing.T) {
result := android.GroupFixturePreparers( result := android.GroupFixturePreparers(
prepareForTestWithSystemserverclasspathFragment, prepareForTestWithSystemserverclasspathFragment,
prepareForTestWithMyapex, prepareForTestWithMyapex,
dexpreopt.FixtureSetApexSystemServerJars("myapex:foo", "myapex:bar"), dexpreopt.FixtureSetApexSystemServerJars("myapex:foo", "myapex:bar", "myapex:baz"),
).RunTestWithBp(t, ` ).RunTestWithBp(t, `
apex { apex {
name: "myapex", name: "myapex",
@@ -69,11 +70,24 @@ func TestSystemserverclasspathFragmentContents(t *testing.T) {
], ],
} }
java_library {
name: "baz",
srcs: ["d.java"],
installable: true,
dex_preopt: {
profile_guided: true, // ignored
},
apex_available: [
"myapex",
],
}
systemserverclasspath_fragment { systemserverclasspath_fragment {
name: "mysystemserverclasspathfragment", name: "mysystemserverclasspathfragment",
contents: [ contents: [
"foo", "foo",
"bar", "bar",
"baz",
], ],
apex_available: [ apex_available: [
"myapex", "myapex",
@@ -81,17 +95,24 @@ func TestSystemserverclasspathFragmentContents(t *testing.T) {
} }
`) `)
ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex_image", []string{ ctx := result.TestContext
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
"etc/classpaths/systemserverclasspath.pb", "etc/classpaths/systemserverclasspath.pb",
"javalib/foo.jar", "javalib/foo.jar",
"javalib/bar.jar", "javalib/bar.jar",
"javalib/bar.jar.prof", "javalib/bar.jar.prof",
"javalib/baz.jar",
}) })
java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex_image", []string{ java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex_image", []string{
`myapex.key`, `myapex.key`,
`mysystemserverclasspathfragment`, `mysystemserverclasspathfragment`,
}) })
assertProfileGuided(t, ctx, "foo", "android_common_apex10000", false)
assertProfileGuided(t, ctx, "bar", "android_common_apex10000", true)
assertProfileGuided(t, ctx, "baz", "android_common_apex10000", false)
} }
func TestSystemserverclasspathFragmentNoGeneratedProto(t *testing.T) { func TestSystemserverclasspathFragmentNoGeneratedProto(t *testing.T) {
@@ -201,7 +222,7 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
result := android.GroupFixturePreparers( result := android.GroupFixturePreparers(
prepareForTestWithSystemserverclasspathFragment, prepareForTestWithSystemserverclasspathFragment,
prepareForTestWithMyapex, prepareForTestWithMyapex,
dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"), dexpreopt.FixtureSetApexSystemServerJars("myapex:foo", "myapex:bar"),
).RunTestWithBp(t, ` ).RunTestWithBp(t, `
prebuilt_apex { prebuilt_apex {
name: "myapex", name: "myapex",
@@ -224,11 +245,23 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
], ],
} }
java_import {
name: "bar",
jars: ["bar.jar"],
dex_preopt: {
profile_guided: true,
},
apex_available: [
"myapex",
],
}
prebuilt_systemserverclasspath_fragment { prebuilt_systemserverclasspath_fragment {
name: "mysystemserverclasspathfragment", name: "mysystemserverclasspathfragment",
prefer: true, prefer: true,
contents: [ contents: [
"foo", "foo",
"bar",
], ],
apex_available: [ apex_available: [
"myapex", "myapex",
@@ -236,22 +269,34 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
} }
`) `)
java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{ ctx := result.TestContext
java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex", []string{
`myapex.apex.selector`, `myapex.apex.selector`,
`prebuilt_mysystemserverclasspathfragment`, `prebuilt_mysystemserverclasspathfragment`,
}) })
java.CheckModuleDependencies(t, result.TestContext, "mysystemserverclasspathfragment", "android_common_myapex", []string{ java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_myapex", []string{
`myapex.deapexer`, `myapex.deapexer`,
`prebuilt_bar`,
`prebuilt_foo`, `prebuilt_foo`,
}) })
ensureExactDeapexedContents(t, ctx, "myapex", "android_common", []string{
"javalib/foo.jar",
"javalib/bar.jar",
"javalib/bar.jar.prof",
})
assertProfileGuided(t, ctx, "foo", "android_common_myapex", false)
assertProfileGuided(t, ctx, "bar", "android_common_myapex", true)
} }
func TestSystemserverclasspathFragmentStandaloneContents(t *testing.T) { func TestSystemserverclasspathFragmentStandaloneContents(t *testing.T) {
result := android.GroupFixturePreparers( result := android.GroupFixturePreparers(
prepareForTestWithSystemserverclasspathFragment, prepareForTestWithSystemserverclasspathFragment,
prepareForTestWithMyapex, prepareForTestWithMyapex,
dexpreopt.FixtureSetApexStandaloneSystemServerJars("myapex:foo", "myapex:bar"), dexpreopt.FixtureSetApexStandaloneSystemServerJars("myapex:foo", "myapex:bar", "myapex:baz"),
).RunTestWithBp(t, ` ).RunTestWithBp(t, `
apex { apex {
name: "myapex", name: "myapex",
@@ -289,11 +334,24 @@ func TestSystemserverclasspathFragmentStandaloneContents(t *testing.T) {
], ],
} }
java_library {
name: "baz",
srcs: ["d.java"],
dex_preopt: {
profile_guided: true, // ignored
},
installable: true,
apex_available: [
"myapex",
],
}
systemserverclasspath_fragment { systemserverclasspath_fragment {
name: "mysystemserverclasspathfragment", name: "mysystemserverclasspathfragment",
standalone_contents: [ standalone_contents: [
"foo", "foo",
"bar", "bar",
"baz",
], ],
apex_available: [ apex_available: [
"myapex", "myapex",
@@ -301,19 +359,26 @@ func TestSystemserverclasspathFragmentStandaloneContents(t *testing.T) {
} }
`) `)
ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex_image", []string{ ctx := result.TestContext
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
"etc/classpaths/systemserverclasspath.pb", "etc/classpaths/systemserverclasspath.pb",
"javalib/foo.jar", "javalib/foo.jar",
"javalib/bar.jar", "javalib/bar.jar",
"javalib/bar.jar.prof", "javalib/bar.jar.prof",
"javalib/baz.jar",
}) })
assertProfileGuided(t, ctx, "foo", "android_common_apex10000", false)
assertProfileGuided(t, ctx, "bar", "android_common_apex10000", true)
assertProfileGuided(t, ctx, "baz", "android_common_apex10000", false)
} }
func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) { func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) {
result := android.GroupFixturePreparers( result := android.GroupFixturePreparers(
prepareForTestWithSystemserverclasspathFragment, prepareForTestWithSystemserverclasspathFragment,
prepareForTestWithMyapex, prepareForTestWithMyapex,
dexpreopt.FixtureSetApexStandaloneSystemServerJars("myapex:foo"), dexpreopt.FixtureSetApexStandaloneSystemServerJars("myapex:foo", "myapex:bar"),
).RunTestWithBp(t, ` ).RunTestWithBp(t, `
prebuilt_apex { prebuilt_apex {
name: "myapex", name: "myapex",
@@ -336,11 +401,23 @@ func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) {
], ],
} }
java_import {
name: "bar",
jars: ["bar.jar"],
dex_preopt: {
profile_guided: true,
},
apex_available: [
"myapex",
],
}
prebuilt_systemserverclasspath_fragment { prebuilt_systemserverclasspath_fragment {
name: "mysystemserverclasspathfragment", name: "mysystemserverclasspathfragment",
prefer: true, prefer: true,
standalone_contents: [ standalone_contents: [
"foo", "foo",
"bar",
], ],
apex_available: [ apex_available: [
"myapex", "myapex",
@@ -348,8 +425,28 @@ func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) {
} }
`) `)
java.CheckModuleDependencies(t, result.TestContext, "mysystemserverclasspathfragment", "android_common_myapex", []string{ ctx := result.TestContext
java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_myapex", []string{
`myapex.deapexer`, `myapex.deapexer`,
`prebuilt_bar`,
`prebuilt_foo`, `prebuilt_foo`,
}) })
ensureExactDeapexedContents(t, ctx, "myapex", "android_common", []string{
"javalib/foo.jar",
"javalib/bar.jar",
"javalib/bar.jar.prof",
})
assertProfileGuided(t, ctx, "foo", "android_common_myapex", false)
assertProfileGuided(t, ctx, "bar", "android_common_myapex", true)
}
func assertProfileGuided(t *testing.T, ctx *android.TestContext, moduleName string, variant string, expected bool) {
dexpreopt := ctx.ModuleForTests(moduleName, variant).Rule("dexpreopt")
actual := strings.Contains(dexpreopt.RuleParams.Command, "--profile-file=")
if expected != actual {
t.Fatalf("Expected profile-guided to be %v, got %v", expected, actual)
}
} }

View File

@@ -23,11 +23,24 @@ import (
) )
type DexpreopterInterface interface { type DexpreopterInterface interface {
IsInstallable() bool // Structs that embed dexpreopter must implement this. // True if the java module is to be dexed and installed on devices.
// Structs that embed dexpreopter must implement this.
IsInstallable() bool
// True if dexpreopt is disabled for the java module.
dexpreoptDisabled(ctx android.BaseModuleContext) bool dexpreoptDisabled(ctx android.BaseModuleContext) bool
// If the java module is to be installed into an APEX, this list contains information about the
// dexpreopt outputs to be installed on devices. Note that these dexpreopt outputs are installed
// outside of the APEX.
DexpreoptBuiltInstalledForApex() []dexpreopterInstall DexpreoptBuiltInstalledForApex() []dexpreopterInstall
// The Make entries to install the dexpreopt outputs. Derived from
// `DexpreoptBuiltInstalledForApex`.
AndroidMkEntriesForApex() []android.AndroidMkEntries AndroidMkEntriesForApex() []android.AndroidMkEntries
ProfilePathOnHost() android.Path
// See `dexpreopter.outputProfilePathOnHost`.
OutputProfilePathOnHost() android.Path
} }
type dexpreopterInstall struct { type dexpreopterInstall struct {
@@ -78,7 +91,8 @@ func (install dexpreopterInstall) ToMakeEntries() android.AndroidMkEntries {
} }
type dexpreopter struct { type dexpreopter struct {
dexpreoptProperties DexpreoptProperties dexpreoptProperties DexpreoptProperties
importDexpreoptProperties ImportDexpreoptProperties
installPath android.InstallPath installPath android.InstallPath
uncompressedDex bool uncompressedDex bool
@@ -105,8 +119,13 @@ type dexpreopter struct {
// dexpreopt another partition). // dexpreopt another partition).
configPath android.WritablePath configPath android.WritablePath
// The path to the profile on host. // The path to the profile on host that dexpreopter generates. This is used as the input for
profilePathOnHost android.Path // dex2oat.
outputProfilePathOnHost android.Path
// The path to the profile that dexpreopter accepts. It must be in the binary format. If this is
// set, it overrides the profile settings in `dexpreoptProperties`.
inputProfilePathOnHost android.Path
} }
type DexpreoptProperties struct { type DexpreoptProperties struct {
@@ -127,6 +146,18 @@ type DexpreoptProperties struct {
// profile location set by PRODUCT_DEX_PREOPT_PROFILE_DIR, or empty if not found. // profile location set by PRODUCT_DEX_PREOPT_PROFILE_DIR, or empty if not found.
Profile *string `android:"path"` Profile *string `android:"path"`
} }
Dex_preopt_result struct {
// True if profile-guided optimization is actually enabled.
Profile_guided bool
} `blueprint:"mutated"`
}
type ImportDexpreoptProperties struct {
Dex_preopt struct {
// If true, use the profile in the prebuilt APEX to guide optimization. Defaults to false.
Profile_guided *bool
}
} }
func init() { func init() {
@@ -295,7 +326,9 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
var profileClassListing android.OptionalPath var profileClassListing android.OptionalPath
var profileBootListing android.OptionalPath var profileBootListing android.OptionalPath
profileIsTextListing := false profileIsTextListing := false
if BoolDefault(d.dexpreoptProperties.Dex_preopt.Profile_guided, true) { if d.inputProfilePathOnHost != nil {
profileClassListing = android.OptionalPathForPath(d.inputProfilePathOnHost)
} else if BoolDefault(d.dexpreoptProperties.Dex_preopt.Profile_guided, true) && !forPrebuiltApex(ctx) {
// If dex_preopt.profile_guided is not set, default it based on the existence of the // If dex_preopt.profile_guided is not set, default it based on the existence of the
// dexprepot.profile option or the profile class listing. // dexprepot.profile option or the profile class listing.
if String(d.dexpreoptProperties.Dex_preopt.Profile) != "" { if String(d.dexpreoptProperties.Dex_preopt.Profile) != "" {
@@ -310,6 +343,8 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
} }
} }
d.dexpreoptProperties.Dex_preopt_result.Profile_guided = profileClassListing.Valid()
// Full dexpreopt config, used to create dexpreopt build rules. // Full dexpreopt config, used to create dexpreopt build rules.
dexpreoptConfig := &dexpreopt.ModuleConfig{ dexpreoptConfig := &dexpreopt.ModuleConfig{
Name: moduleName(ctx), Name: moduleName(ctx),
@@ -374,7 +409,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
isProfile := strings.HasSuffix(installBase, ".prof") isProfile := strings.HasSuffix(installBase, ".prof")
if isProfile { if isProfile {
d.profilePathOnHost = install.From d.outputProfilePathOnHost = install.From
} }
if isApexSystemServerJar { if isApexSystemServerJar {
@@ -416,6 +451,6 @@ func (d *dexpreopter) AndroidMkEntriesForApex() []android.AndroidMkEntries {
return entries return entries
} }
func (d *dexpreopter) ProfilePathOnHost() android.Path { func (d *dexpreopter) OutputProfilePathOnHost() android.Path {
return d.profilePathOnHost return d.outputProfilePathOnHost
} }

View File

@@ -801,6 +801,8 @@ type librarySdkMemberProperties struct {
// The value of the min_sdk_version property, translated into a number where possible. // The value of the min_sdk_version property, translated into a number where possible.
MinSdkVersion *string `supported_build_releases:"Tiramisu+"` MinSdkVersion *string `supported_build_releases:"Tiramisu+"`
DexPreoptProfileGuided *bool `supported_build_releases:"UpsideDownCake+"`
} }
func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
@@ -818,6 +820,10 @@ func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberCo
canonical := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.ApiLevel.String()) canonical := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.ApiLevel.String())
p.MinSdkVersion = proptools.StringPtr(canonical) p.MinSdkVersion = proptools.StringPtr(canonical)
} }
if j.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided {
p.DexPreoptProfileGuided = proptools.BoolPtr(true)
}
} }
func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
@@ -844,6 +850,11 @@ func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberConte
propertySet.AddProperty("permitted_packages", p.PermittedPackages) propertySet.AddProperty("permitted_packages", p.PermittedPackages)
} }
dexPreoptSet := propertySet.AddPropertySet("dex_preopt")
if p.DexPreoptProfileGuided != nil {
dexPreoptSet.AddProperty("profile_guided", proptools.Bool(p.DexPreoptProfileGuided))
}
// Do not copy anything else to the snapshot. // Do not copy anything else to the snapshot.
if memberType.onlyCopyJarToSnapshot { if memberType.onlyCopyJarToSnapshot {
return return
@@ -2014,7 +2025,8 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if di == nil { if di == nil {
return // An error has been reported by FindDeapexerProviderForModule. return // An error has been reported by FindDeapexerProviderForModule.
} }
if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil { dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(j.BaseModuleName())
if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil {
dexJarFile := makeDexJarPathFromPath(dexOutputPath) dexJarFile := makeDexJarPathFromPath(dexOutputPath)
j.dexJarFile = dexJarFile j.dexJarFile = dexJarFile
installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName())) installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName()))
@@ -2023,6 +2035,11 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, installPath) j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, installPath)
setUncompressDex(ctx, &j.dexpreopter, &j.dexer) setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
if profilePath := di.PrebuiltExportPath(dexJarFileApexRootRelative + ".prof"); profilePath != nil {
j.dexpreopter.inputProfilePathOnHost = profilePath
}
j.dexpreopt(ctx, dexOutputPath) j.dexpreopt(ctx, dexOutputPath)
// Initialize the hiddenapi structure. // Initialize the hiddenapi structure.
@@ -2157,11 +2174,16 @@ func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
// requiredFilesFromPrebuiltApexForImport returns information about the files that a java_import or // requiredFilesFromPrebuiltApexForImport returns information about the files that a java_import or
// java_sdk_library_import with the specified base module name requires to be exported from a // java_sdk_library_import with the specified base module name requires to be exported from a
// prebuilt_apex/apex_set. // prebuilt_apex/apex_set.
func requiredFilesFromPrebuiltApexForImport(name string) []string { func requiredFilesFromPrebuiltApexForImport(name string, d *dexpreopter) []string {
dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(name)
// Add the dex implementation jar to the set of exported files. // Add the dex implementation jar to the set of exported files.
return []string{ files := []string{
apexRootRelativePathToJavaLib(name), dexJarFileApexRootRelative,
} }
if BoolDefault(d.importDexpreoptProperties.Dex_preopt.Profile_guided, false) {
files = append(files, dexJarFileApexRootRelative+".prof")
}
return files
} }
// apexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for // apexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for
@@ -2174,7 +2196,7 @@ var _ android.RequiredFilesFromPrebuiltApex = (*Import)(nil)
func (j *Import) RequiredFilesFromPrebuiltApex(_ android.BaseModuleContext) []string { func (j *Import) RequiredFilesFromPrebuiltApex(_ android.BaseModuleContext) []string {
name := j.BaseModuleName() name := j.BaseModuleName()
return requiredFilesFromPrebuiltApexForImport(name) return requiredFilesFromPrebuiltApexForImport(name, &j.dexpreopter)
} }
// Add compile time check for interface implementation // Add compile time check for interface implementation
@@ -2215,6 +2237,7 @@ func ImportFactory() android.Module {
module.AddProperties( module.AddProperties(
&module.properties, &module.properties,
&module.dexer.dexProperties, &module.dexer.dexProperties,
&module.importDexpreoptProperties,
) )
module.initModuleAndImport(module) module.initModuleAndImport(module)

View File

@@ -2243,7 +2243,7 @@ func sdkLibraryImportFactory() android.Module {
allScopeProperties, scopeToProperties := createPropertiesInstance() allScopeProperties, scopeToProperties := createPropertiesInstance()
module.scopeProperties = scopeToProperties module.scopeProperties = scopeToProperties
module.AddProperties(&module.properties, allScopeProperties) module.AddProperties(&module.properties, allScopeProperties, &module.importDexpreoptProperties)
// Initialize information common between source and prebuilt. // Initialize information common between source and prebuilt.
module.initCommon(module) module.initCommon(module)
@@ -2487,18 +2487,24 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
if di == nil { if di == nil {
return // An error has been reported by FindDeapexerProviderForModule. return // An error has been reported by FindDeapexerProviderForModule.
} }
if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(module.BaseModuleName())); dexOutputPath != nil { dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(module.BaseModuleName())
if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil {
dexJarFile := makeDexJarPathFromPath(dexOutputPath) dexJarFile := makeDexJarPathFromPath(dexOutputPath)
module.dexJarFile = dexJarFile module.dexJarFile = dexJarFile
installPath := android.PathForModuleInPartitionInstall( installPath := android.PathForModuleInPartitionInstall(
ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(module.BaseModuleName())) ctx, "apex", ai.ApexVariationName, dexJarFileApexRootRelative)
module.installFile = installPath module.installFile = installPath
module.initHiddenAPI(ctx, dexJarFile, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil) module.initHiddenAPI(ctx, dexJarFile, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil)
// Dexpreopting.
module.dexpreopter.installPath = module.dexpreopter.getInstallPath(ctx, installPath) module.dexpreopter.installPath = module.dexpreopter.getInstallPath(ctx, installPath)
module.dexpreopter.isSDKLibrary = true module.dexpreopter.isSDKLibrary = true
module.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &module.dexpreopter) module.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &module.dexpreopter)
if profilePath := di.PrebuiltExportPath(dexJarFileApexRootRelative + ".prof"); profilePath != nil {
module.dexpreopter.inputProfilePathOnHost = profilePath
}
// Dexpreopting.
module.dexpreopt(ctx, dexOutputPath) module.dexpreopt(ctx, dexOutputPath)
} else { } else {
// This should never happen as a variant for a prebuilt_apex is only created if the // This should never happen as a variant for a prebuilt_apex is only created if the
@@ -2627,7 +2633,7 @@ var _ android.RequiredFilesFromPrebuiltApex = (*SdkLibraryImport)(nil)
func (module *SdkLibraryImport) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string { func (module *SdkLibraryImport) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string {
name := module.BaseModuleName() name := module.BaseModuleName()
return requiredFilesFromPrebuiltApexForImport(name) return requiredFilesFromPrebuiltApexForImport(name, &module.dexpreopter)
} }
// java_sdk_library_xml // java_sdk_library_xml
@@ -3036,6 +3042,8 @@ type sdkLibrarySdkMemberProperties struct {
// //
// This means that the device won't recognise this library as installed. // This means that the device won't recognise this library as installed.
Max_device_sdk *string Max_device_sdk *string
DexPreoptProfileGuided *bool `supported_build_releases:"UpsideDownCake+"`
} }
type scopeProperties struct { type scopeProperties struct {
@@ -3089,6 +3097,10 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe
s.On_bootclasspath_before = sdk.commonSdkLibraryProperties.On_bootclasspath_before s.On_bootclasspath_before = sdk.commonSdkLibraryProperties.On_bootclasspath_before
s.Min_device_sdk = sdk.commonSdkLibraryProperties.Min_device_sdk s.Min_device_sdk = sdk.commonSdkLibraryProperties.Min_device_sdk
s.Max_device_sdk = sdk.commonSdkLibraryProperties.Max_device_sdk s.Max_device_sdk = sdk.commonSdkLibraryProperties.Max_device_sdk
if sdk.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided {
s.DexPreoptProfileGuided = proptools.BoolPtr(true)
}
} }
func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
@@ -3104,6 +3116,10 @@ func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberCo
if len(s.Permitted_packages) > 0 { if len(s.Permitted_packages) > 0 {
propertySet.AddProperty("permitted_packages", s.Permitted_packages) propertySet.AddProperty("permitted_packages", s.Permitted_packages)
} }
dexPreoptSet := propertySet.AddPropertySet("dex_preopt")
if s.DexPreoptProfileGuided != nil {
dexPreoptSet.AddProperty("profile_guided", proptools.Bool(s.DexPreoptProfileGuided))
}
stem := s.Stem stem := s.Stem

View File

@@ -33,7 +33,8 @@ var prepareForSdkTestWithJava = android.GroupFixturePreparers(
// Files needs by most of the tests. // Files needs by most of the tests.
android.MockFS{ android.MockFS{
"Test.java": nil, "Test.java": nil,
"art-profile": nil,
}.AddToFixture(), }.AddToFixture(),
) )

View File

@@ -62,6 +62,9 @@ func testSnapshotWithSystemServerClasspathFragment(t *testing.T, sdk string, tar
min_sdk_version: "2", min_sdk_version: "2",
compile_dex: true, compile_dex: true,
permitted_packages: ["mylib"], permitted_packages: ["mylib"],
dex_preopt: {
profile: "art-profile",
},
} }
java_sdk_library { java_sdk_library {
@@ -71,6 +74,9 @@ func testSnapshotWithSystemServerClasspathFragment(t *testing.T, sdk string, tar
shared_library: false, shared_library: false,
public: {enabled: true}, public: {enabled: true},
min_sdk_version: "2", min_sdk_version: "2",
dex_preopt: {
profile: "art-profile",
},
} }
`), `),
).RunTest(t) ).RunTest(t)
@@ -105,6 +111,9 @@ java_sdk_library_import {
visibility: ["//visibility:public"], visibility: ["//visibility:public"],
apex_available: ["myapex"], apex_available: ["myapex"],
shared_library: false, shared_library: false,
dex_preopt: {
profile_guided: true,
},
public: { public: {
jars: ["sdk_library/public/mysdklibrary-stubs.jar"], jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"], stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
@@ -122,6 +131,9 @@ java_import {
jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"], jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"],
min_sdk_version: "2", min_sdk_version: "2",
permitted_packages: ["mylib"], permitted_packages: ["mylib"],
dex_preopt: {
profile_guided: true,
},
} }
prebuilt_systemserverclasspath_fragment { prebuilt_systemserverclasspath_fragment {
@@ -186,6 +198,54 @@ java_import {
permitted_packages: ["mylib"], permitted_packages: ["mylib"],
} }
prebuilt_systemserverclasspath_fragment {
name: "mysystemserverclasspathfragment",
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["myapex"],
contents: [
"mylib",
"mysdklibrary",
],
}
`)
})
t.Run("target-u", func(t *testing.T) {
testSnapshotWithSystemServerClasspathFragment(t, commonSdk, "UpsideDownCake", `
// This is auto-generated. DO NOT EDIT.
java_sdk_library_import {
name: "mysdklibrary",
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["myapex"],
shared_library: false,
dex_preopt: {
profile_guided: true,
},
public: {
jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
current_api: "sdk_library/public/mysdklibrary.txt",
removed_api: "sdk_library/public/mysdklibrary-removed.txt",
sdk_version: "current",
},
}
java_import {
name: "mylib",
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["myapex"],
jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"],
min_sdk_version: "2",
permitted_packages: ["mylib"],
dex_preopt: {
profile_guided: true,
},
}
prebuilt_systemserverclasspath_fragment { prebuilt_systemserverclasspath_fragment {
name: "mysystemserverclasspathfragment", name: "mysystemserverclasspathfragment",
prefer: false, prefer: false,