Loading apex/bootclasspath_fragment_test.go +2 −2 Original line number Diff line number Diff line Loading @@ -522,8 +522,8 @@ func TestBootclasspathFragmentContentsNoName(t *testing.T) { android.AssertStringDoesContain(t, name+" apex copy command", copyCommands, expectedCopyCommand) } checkFragmentExportedDexJar("foo", "out/soong/.intermediates/foo/android_common_apex10000/hiddenapi/foo.jar") checkFragmentExportedDexJar("bar", "out/soong/.intermediates/bar/android_common_apex10000/hiddenapi/bar.jar") checkFragmentExportedDexJar("foo", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/foo.jar") checkFragmentExportedDexJar("bar", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/bar.jar") } // TODO(b/177892522) - add test for host apex. java/bootclasspath_fragment.go +35 −12 Original line number Diff line number Diff line Loading @@ -386,7 +386,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo }) // 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 // prebuilt which will not use the image config. Loading @@ -395,20 +395,20 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo // A prebuilt fragment cannot contribute to the apex. if !android.IsModulePrebuilt(ctx.Module()) { // 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 // 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. info := BootclasspathFragmentApexContentInfo{ imageConfig: imageConfig, } // 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) { // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars Loading @@ -425,14 +425,35 @@ func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleC // populateApexContentInfoDexJars adds paths to the dex jars provided by this fragment to the // 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{} 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 { j := m.(UsesLibraryDependency) dexJar := j.DexJarBuildPath() info.contentModuleDexJarPaths[m.Name()] = dexJar } } } // generateClasspathProtoBuildActions generates all required build actions for classpath.proto config func (b *BootclasspathFragmentModule) generateClasspathProtoBuildActions(ctx android.ModuleContext) { Loading Loading @@ -506,13 +527,13 @@ func (b *BootclasspathFragmentModule) canPerformHiddenAPIProcessing(ctx android. } // 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 // appropriate information needed for hidden API processing breaking the build. if !b.canPerformHiddenAPIProcessing(ctx) { // Nothing to do. return return nil } // Convert the kind specific lists of modules into kind specific lists of jars. Loading @@ -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 // cannot do that. if len(stubJarsByKind) == 0 { return return nil } // Store the information for use by other modules. Loading @@ -541,6 +562,8 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android. // Store the information for use by platform_bootclasspath. ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo) return &flagFileInfo } // produceHiddenAPIAllFlagsFile produces the hidden API all-flags.csv file (and supporting files) Loading java/hiddenapi.go +26 −24 Original line number Diff line number Diff line Loading @@ -145,15 +145,13 @@ func (h *hiddenAPI) hiddenAPIEncodeDex(ctx android.ModuleContext, dexJar android } uncompressDex := *h.uncompressDexState hiddenAPIJar := android.PathForModuleOut(ctx, "hiddenapi", dexJar.Base()).OutputPath // Create a copy of the dex jar which has been encoded with hiddenapi flags. hiddenAPIEncodeDex(ctx, hiddenAPIJar, dexJar, uncompressDex) flagsCSV := hiddenAPISingletonPaths(ctx).flags outputDir := android.PathForModuleOut(ctx, "hiddenapi").OutputPath encodedDex := hiddenAPIEncodeDex(ctx, dexJar, flagsCSV, uncompressDex, outputDir) // Use the encoded dex jar from here onwards. dexJar = hiddenAPIJar return dexJar return encodedDex } // buildRuleToGenerateAnnotationFlags builds a ninja rule to generate the annotation-flags.csv file Loading Loading @@ -243,35 +241,37 @@ var hiddenAPIEncodeDexRule = pctx.AndroidStaticRule("hiddenAPIEncodeDex", bluepr }, }, "flagsCsv", "hiddenapiFlags", "tmpDir", "soongZipFlags") func hiddenAPIEncodeDex(ctx android.ModuleContext, output android.WritablePath, dexInput android.Path, uncompressDex bool) { // hiddenAPIEncodeDex generates the build rule that will encode the supplied dex jar and place the // encoded dex jar in a file of the same name in the output directory. // // The encode dex rule requires unzipping, encoding and rezipping the classes.dex files along with // all the resources from the input jar. It also ensures that if it was uncompressed in the input // it stays uncompressed in the output. func hiddenAPIEncodeDex(ctx android.ModuleContext, dexInput, flagsCSV android.Path, uncompressDex bool, outputDir android.OutputPath) android.OutputPath { flagsCSV := hiddenAPISingletonPaths(ctx).flags // The output file has the same name as the input file and is in the output directory. output := outputDir.Join(ctx, dexInput.Base()) // Create a jar specific temporary directory in which to do the work just in case this is called // with the same output directory for multiple modules. tmpDir := outputDir.Join(ctx, dexInput.Base()+"-tmp") // The encode dex rule requires unzipping and rezipping the classes.dex files, ensure that if it was uncompressed // in the input it stays uncompressed in the output. // If the input is uncompressed then generate the output of the encode rule to an intermediate // file as the final output will need further processing after encoding. soongZipFlags := "" hiddenapiFlags := "" tmpOutput := output tmpDir := android.PathForModuleOut(ctx, "hiddenapi", "dex") encodeRuleOutput := output if uncompressDex { soongZipFlags = "-L 0" tmpOutput = android.PathForModuleOut(ctx, "hiddenapi", "unaligned", "unaligned.jar") tmpDir = android.PathForModuleOut(ctx, "hiddenapi", "unaligned") encodeRuleOutput = outputDir.Join(ctx, "unaligned", dexInput.Base()) } enforceHiddenApiFlagsToAllMembers := true // b/149353192: when a module is instrumented, jacoco adds synthetic members // $jacocoData and $jacocoInit. Since they don't exist when building the hidden API flags, // don't complain when we don't find hidden API flags for the synthetic members. hiddenapiFlags := "" if j, ok := ctx.Module().(interface { shouldInstrument(android.BaseModuleContext) bool }); ok && j.shouldInstrument(ctx) { enforceHiddenApiFlagsToAllMembers = false } if !enforceHiddenApiFlagsToAllMembers { hiddenapiFlags = "--no-force-assign-all" } Loading @@ -279,7 +279,7 @@ func hiddenAPIEncodeDex(ctx android.ModuleContext, output android.WritablePath, Rule: hiddenAPIEncodeDexRule, Description: "hiddenapi encode dex", Input: dexInput, Output: tmpOutput, Output: encodeRuleOutput, Implicit: flagsCSV, Args: map[string]string{ "flagsCsv": flagsCSV.String(), Loading @@ -290,8 +290,10 @@ func hiddenAPIEncodeDex(ctx android.ModuleContext, output android.WritablePath, }) if uncompressDex { TransformZipAlign(ctx, output, tmpOutput) TransformZipAlign(ctx, output, encodeRuleOutput) } return output } type hiddenApiAnnotationsDependencyTag struct { Loading Loading
apex/bootclasspath_fragment_test.go +2 −2 Original line number Diff line number Diff line Loading @@ -522,8 +522,8 @@ func TestBootclasspathFragmentContentsNoName(t *testing.T) { android.AssertStringDoesContain(t, name+" apex copy command", copyCommands, expectedCopyCommand) } checkFragmentExportedDexJar("foo", "out/soong/.intermediates/foo/android_common_apex10000/hiddenapi/foo.jar") checkFragmentExportedDexJar("bar", "out/soong/.intermediates/bar/android_common_apex10000/hiddenapi/bar.jar") checkFragmentExportedDexJar("foo", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/foo.jar") checkFragmentExportedDexJar("bar", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/bar.jar") } // TODO(b/177892522) - add test for host apex.
java/bootclasspath_fragment.go +35 −12 Original line number Diff line number Diff line Loading @@ -386,7 +386,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo }) // 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 // prebuilt which will not use the image config. Loading @@ -395,20 +395,20 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo // A prebuilt fragment cannot contribute to the apex. if !android.IsModulePrebuilt(ctx.Module()) { // 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 // 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. info := BootclasspathFragmentApexContentInfo{ imageConfig: imageConfig, } // 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) { // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars Loading @@ -425,14 +425,35 @@ func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleC // populateApexContentInfoDexJars adds paths to the dex jars provided by this fragment to the // 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{} 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 { j := m.(UsesLibraryDependency) dexJar := j.DexJarBuildPath() info.contentModuleDexJarPaths[m.Name()] = dexJar } } } // generateClasspathProtoBuildActions generates all required build actions for classpath.proto config func (b *BootclasspathFragmentModule) generateClasspathProtoBuildActions(ctx android.ModuleContext) { Loading Loading @@ -506,13 +527,13 @@ func (b *BootclasspathFragmentModule) canPerformHiddenAPIProcessing(ctx android. } // 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 // appropriate information needed for hidden API processing breaking the build. if !b.canPerformHiddenAPIProcessing(ctx) { // Nothing to do. return return nil } // Convert the kind specific lists of modules into kind specific lists of jars. Loading @@ -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 // cannot do that. if len(stubJarsByKind) == 0 { return return nil } // Store the information for use by other modules. Loading @@ -541,6 +562,8 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android. // Store the information for use by platform_bootclasspath. ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo) return &flagFileInfo } // produceHiddenAPIAllFlagsFile produces the hidden API all-flags.csv file (and supporting files) Loading
java/hiddenapi.go +26 −24 Original line number Diff line number Diff line Loading @@ -145,15 +145,13 @@ func (h *hiddenAPI) hiddenAPIEncodeDex(ctx android.ModuleContext, dexJar android } uncompressDex := *h.uncompressDexState hiddenAPIJar := android.PathForModuleOut(ctx, "hiddenapi", dexJar.Base()).OutputPath // Create a copy of the dex jar which has been encoded with hiddenapi flags. hiddenAPIEncodeDex(ctx, hiddenAPIJar, dexJar, uncompressDex) flagsCSV := hiddenAPISingletonPaths(ctx).flags outputDir := android.PathForModuleOut(ctx, "hiddenapi").OutputPath encodedDex := hiddenAPIEncodeDex(ctx, dexJar, flagsCSV, uncompressDex, outputDir) // Use the encoded dex jar from here onwards. dexJar = hiddenAPIJar return dexJar return encodedDex } // buildRuleToGenerateAnnotationFlags builds a ninja rule to generate the annotation-flags.csv file Loading Loading @@ -243,35 +241,37 @@ var hiddenAPIEncodeDexRule = pctx.AndroidStaticRule("hiddenAPIEncodeDex", bluepr }, }, "flagsCsv", "hiddenapiFlags", "tmpDir", "soongZipFlags") func hiddenAPIEncodeDex(ctx android.ModuleContext, output android.WritablePath, dexInput android.Path, uncompressDex bool) { // hiddenAPIEncodeDex generates the build rule that will encode the supplied dex jar and place the // encoded dex jar in a file of the same name in the output directory. // // The encode dex rule requires unzipping, encoding and rezipping the classes.dex files along with // all the resources from the input jar. It also ensures that if it was uncompressed in the input // it stays uncompressed in the output. func hiddenAPIEncodeDex(ctx android.ModuleContext, dexInput, flagsCSV android.Path, uncompressDex bool, outputDir android.OutputPath) android.OutputPath { flagsCSV := hiddenAPISingletonPaths(ctx).flags // The output file has the same name as the input file and is in the output directory. output := outputDir.Join(ctx, dexInput.Base()) // Create a jar specific temporary directory in which to do the work just in case this is called // with the same output directory for multiple modules. tmpDir := outputDir.Join(ctx, dexInput.Base()+"-tmp") // The encode dex rule requires unzipping and rezipping the classes.dex files, ensure that if it was uncompressed // in the input it stays uncompressed in the output. // If the input is uncompressed then generate the output of the encode rule to an intermediate // file as the final output will need further processing after encoding. soongZipFlags := "" hiddenapiFlags := "" tmpOutput := output tmpDir := android.PathForModuleOut(ctx, "hiddenapi", "dex") encodeRuleOutput := output if uncompressDex { soongZipFlags = "-L 0" tmpOutput = android.PathForModuleOut(ctx, "hiddenapi", "unaligned", "unaligned.jar") tmpDir = android.PathForModuleOut(ctx, "hiddenapi", "unaligned") encodeRuleOutput = outputDir.Join(ctx, "unaligned", dexInput.Base()) } enforceHiddenApiFlagsToAllMembers := true // b/149353192: when a module is instrumented, jacoco adds synthetic members // $jacocoData and $jacocoInit. Since they don't exist when building the hidden API flags, // don't complain when we don't find hidden API flags for the synthetic members. hiddenapiFlags := "" if j, ok := ctx.Module().(interface { shouldInstrument(android.BaseModuleContext) bool }); ok && j.shouldInstrument(ctx) { enforceHiddenApiFlagsToAllMembers = false } if !enforceHiddenApiFlagsToAllMembers { hiddenapiFlags = "--no-force-assign-all" } Loading @@ -279,7 +279,7 @@ func hiddenAPIEncodeDex(ctx android.ModuleContext, output android.WritablePath, Rule: hiddenAPIEncodeDexRule, Description: "hiddenapi encode dex", Input: dexInput, Output: tmpOutput, Output: encodeRuleOutput, Implicit: flagsCSV, Args: map[string]string{ "flagsCsv": flagsCSV.String(), Loading @@ -290,8 +290,10 @@ func hiddenAPIEncodeDex(ctx android.ModuleContext, output android.WritablePath, }) if uncompressDex { TransformZipAlign(ctx, output, tmpOutput) TransformZipAlign(ctx, output, encodeRuleOutput) } return output } type hiddenApiAnnotationsDependencyTag struct { Loading