Perform hidden API encoding in bootclasspath_fragment

Previously, the apex content info was populated with hidden API encoded
dex jars retrieved directly from the java module. This change retrieves
the unencoded dex jars from the java module, encodes them and then
stores the result in the apex content info.

Bug: 179354495
Test: m com.android.art com.android.ipsec com.android.os.statsd com.android.conscrypt
      - verify that this does not change the contents of the apex files
Change-Id: Ib1b6eb8b62ac50e03b9e0d07c877ca70bb6f6d25
This commit is contained in:
Paul Duffin 2021-05-15 08:54:30 +01:00
parent 0916595b1c
commit 54c98f5b4a
2 changed files with 37 additions and 14 deletions

View file

@ -522,8 +522,8 @@ func TestBootclasspathFragmentContentsNoName(t *testing.T) {
android.AssertStringDoesContain(t, name+" apex copy command", copyCommands, expectedCopyCommand) android.AssertStringDoesContain(t, name+" apex copy command", copyCommands, expectedCopyCommand)
} }
checkFragmentExportedDexJar("foo", "out/soong/.intermediates/foo/android_common_apex10000/hiddenapi/foo.jar") checkFragmentExportedDexJar("foo", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/foo.jar")
checkFragmentExportedDexJar("bar", "out/soong/.intermediates/bar/android_common_apex10000/hiddenapi/bar.jar") checkFragmentExportedDexJar("bar", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/bar.jar")
} }
// TODO(b/177892522) - add test for host apex. // TODO(b/177892522) - add test for host apex.

View file

@ -386,7 +386,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
}) })
// Perform hidden API processing. // Perform hidden API processing.
b.generateHiddenAPIBuildActions(ctx, contents) hiddenAPIInfo := b.generateHiddenAPIBuildActions(ctx, contents)
// Verify that the image_name specified on a bootclasspath_fragment is valid even if this is a // Verify that the image_name specified on a bootclasspath_fragment is valid even if this is a
// prebuilt which will not use the image config. // prebuilt which will not use the image config.
@ -395,20 +395,20 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
// A prebuilt fragment cannot contribute to the apex. // A prebuilt fragment cannot contribute to the apex.
if !android.IsModulePrebuilt(ctx.Module()) { if !android.IsModulePrebuilt(ctx.Module()) {
// Provide the apex content info. // Provide the apex content info.
b.provideApexContentInfo(ctx, imageConfig, contents) b.provideApexContentInfo(ctx, imageConfig, contents, hiddenAPIInfo)
} }
} }
// provideApexContentInfo creates, initializes and stores the apex content info for use by other // provideApexContentInfo creates, initializes and stores the apex content info for use by other
// modules. // modules.
func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, contents []android.Module) { func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, contents []android.Module, hiddenAPIInfo *hiddenAPIFlagFileInfo) {
// Construct the apex content info from the config. // Construct the apex content info from the config.
info := BootclasspathFragmentApexContentInfo{ info := BootclasspathFragmentApexContentInfo{
imageConfig: imageConfig, imageConfig: imageConfig,
} }
// Populate the apex content info with paths to the dex jars. // Populate the apex content info with paths to the dex jars.
b.populateApexContentInfoDexJars(ctx, &info, contents) b.populateApexContentInfoDexJars(ctx, &info, contents, hiddenAPIInfo)
if !SkipDexpreoptBootJars(ctx) { if !SkipDexpreoptBootJars(ctx) {
// Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
@ -425,13 +425,34 @@ func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleC
// populateApexContentInfoDexJars adds paths to the dex jars provided by this fragment to the // populateApexContentInfoDexJars adds paths to the dex jars provided by this fragment to the
// apex content info. // apex content info.
func (b *BootclasspathFragmentModule) populateApexContentInfoDexJars(ctx android.ModuleContext, info *BootclasspathFragmentApexContentInfo, contents []android.Module) { func (b *BootclasspathFragmentModule) populateApexContentInfoDexJars(ctx android.ModuleContext, info *BootclasspathFragmentApexContentInfo, contents []android.Module, hiddenAPIInfo *hiddenAPIFlagFileInfo) {
info.contentModuleDexJarPaths = map[string]android.Path{} info.contentModuleDexJarPaths = map[string]android.Path{}
if hiddenAPIInfo != nil {
// Hidden API encoding has been performed.
flags := hiddenAPIInfo.AllFlagsPaths[0]
for _, m := range contents {
h := m.(hiddenAPIModule)
unencodedDex := h.bootDexJar()
if unencodedDex == nil {
// This is an error. Sometimes Soong will report the error directly, other times it will
// defer the error reporting to happen only when trying to use the missing file in ninja.
// Either way it is handled by extractBootDexJarsFromHiddenAPIModules which must have been
// called before this as it generates the flags that are used to encode these files.
continue
}
outputDir := android.PathForModuleOut(ctx, "hiddenapi-modular/encoded").OutputPath
encodedDex := hiddenAPIEncodeDex(ctx, unencodedDex, flags, *h.uncompressDex(), outputDir)
info.contentModuleDexJarPaths[m.Name()] = encodedDex
}
} else {
for _, m := range contents { for _, m := range contents {
j := m.(UsesLibraryDependency) j := m.(UsesLibraryDependency)
dexJar := j.DexJarBuildPath() dexJar := j.DexJarBuildPath()
info.contentModuleDexJarPaths[m.Name()] = dexJar info.contentModuleDexJarPaths[m.Name()] = dexJar
} }
}
} }
// generateClasspathProtoBuildActions generates all required build actions for classpath.proto config // generateClasspathProtoBuildActions generates all required build actions for classpath.proto config
@ -506,13 +527,13 @@ func (b *BootclasspathFragmentModule) canPerformHiddenAPIProcessing(ctx android.
} }
// generateHiddenAPIBuildActions generates all the hidden API related build rules. // generateHiddenAPIBuildActions generates all the hidden API related build rules.
func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.Module) { func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.Module) *hiddenAPIFlagFileInfo {
// A temporary workaround to avoid existing bootclasspath_fragments that do not provide the // A temporary workaround to avoid existing bootclasspath_fragments that do not provide the
// appropriate information needed for hidden API processing breaking the build. // appropriate information needed for hidden API processing breaking the build.
if !b.canPerformHiddenAPIProcessing(ctx) { if !b.canPerformHiddenAPIProcessing(ctx) {
// Nothing to do. // Nothing to do.
return return nil
} }
// Convert the kind specific lists of modules into kind specific lists of jars. // Convert the kind specific lists of modules into kind specific lists of jars.
@ -523,7 +544,7 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.
// the bootclasspath in order to be used by something else in the system. Without any stubs it // the bootclasspath in order to be used by something else in the system. Without any stubs it
// cannot do that. // cannot do that.
if len(stubJarsByKind) == 0 { if len(stubJarsByKind) == 0 {
return return nil
} }
// Store the information for use by other modules. // Store the information for use by other modules.
@ -541,6 +562,8 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.
// Store the information for use by platform_bootclasspath. // Store the information for use by platform_bootclasspath.
ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo) ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo)
return &flagFileInfo
} }
// produceHiddenAPIAllFlagsFile produces the hidden API all-flags.csv file (and supporting files) // produceHiddenAPIAllFlagsFile produces the hidden API all-flags.csv file (and supporting files)