Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 699a0048 authored by Paul Duffin's avatar Paul Duffin
Browse files

Fix hidden API flags in com.android.i18n

Change 70cfdff3 changed the hidden API
flags in com.android.i18n as it stopped the i18n-bootclasspath-fragment
from making the hidden API flag files available for use by
platform-bootclasspath.

This change fixes that by exporting the flag files even if hidden API
flag generation is skipped.

Bug: 179354495
Test: m com.android.i18 out/soong/hiddenapi/hiddenapi-flags.csv
      - make sure that the flags in
        packages/modules/RuntimeI18n/apex/hiddenapi/hiddenapi-max-target-o-low-priority.txt
        are reflected in the core-icu4j dex files in the apex.
Merged-In: I9b5c7c74bd996ab447bc0e0452da5fd49191a35d
Change-Id: I9b5c7c74bd996ab447bc0e0452da5fd49191a35d
(cherry picked from commit 62370923)
parent 71955b4b
Loading
Loading
Loading
Loading
+24 −49
Original line number Diff line number Diff line
@@ -501,73 +501,48 @@ func (b *BootclasspathFragmentModule) getImageConfig(ctx android.EarlyModuleCont
	return imageConfig
}

// canPerformHiddenAPIProcessing determines whether hidden API processing should be performed.
//
// A temporary workaround to avoid existing bootclasspath_fragments that do not provide the
// appropriate information needed for hidden API processing breaking the build.
// TODO(b/179354495): Remove this workaround.
func (b *BootclasspathFragmentModule) canPerformHiddenAPIProcessing(ctx android.ModuleContext) bool {
	// Hidden API processing is always enabled in tests.
	if ctx.Config().TestProductVariables != nil {
		return true
	}
	// A module that has fragments should have access to the information it needs in order to perform
	// hidden API processing.
	if len(b.properties.Fragments) != 0 {
		return true
	}

	// The art bootclasspath fragment does not depend on any other fragments but already supports
	// hidden API processing.
	imageName := proptools.String(b.properties.Image_name)
	if imageName == "art" {
		return true
	}

	// Disable it for everything else.
	return false
}

// generateHiddenAPIBuildActions generates all the hidden API related build rules.
func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.Module) *HiddenAPIFlagOutput {

	// 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 nil
	}

	// Create hidden API input structure.
	input := b.createHiddenAPIFlagInput(ctx, contents)

	// Performing hidden API processing without stubs is not supported and it is unlikely to ever be
	// required as the whole point of adding something to the bootclasspath fragment is to add it to
	// the bootclasspath in order to be used by something else in the system. Without any stubs it
	// cannot do that.
	if len(input.StubDexJarsByKind) == 0 {
		return nil
	}

	// Store the information for use by other modules.
	bootclasspathApiInfo := bootclasspathApiInfo{stubJarsByKind: input.StubDexJarsByKind}
	ctx.SetProvider(bootclasspathApiInfoProvider, bootclasspathApiInfo)

	var output *HiddenAPIFlagOutput

	// Hidden API processing is conditional as a temporary workaround as not all
	// bootclasspath_fragments provide the appropriate information needed for hidden API processing
	// which leads to breakages of the build.
	// TODO(b/179354495): Stop hidden API processing being conditional once all bootclasspath_fragment
	//  modules have been updated to support it.
	if input.canPerformHiddenAPIProcessing(ctx, b.properties) {
		// Get the content modules that contribute to the hidden API processing.
		hiddenAPIModules := gatherHiddenAPIModuleFromContents(ctx, contents)

		// Delegate the production of the hidden API all-flags.csv file to a module type specific method.
		common := ctx.Module().(commonBootclasspathFragment)
	output := common.produceHiddenAPIAllFlagsFile(ctx, hiddenAPIModules, input)
		output = common.produceHiddenAPIAllFlagsFile(ctx, hiddenAPIModules, input)
	}

	// Initialize a HiddenAPIInfo structure and provide it for use by other modules.
	// Initialize a HiddenAPIInfo structure.
	hiddenAPIInfo := HiddenAPIInfo{
		// The monolithic hidden API processing needs access to the flag files from all the fragments.
		// The monolithic hidden API processing needs access to the flag files that override the default
		// flags from all the fragments whether or not they actually perform their own hidden API flag
		// generation. That is because the monolithic hidden API processing uses those flag files to
		// perform its own flag generation.
		FlagFilesByCategory: input.FlagFilesByCategory,
	}

	if output != nil {
		// The monolithic hidden API processing also needs access to all the output files produced by
		// hidden API processing of this fragment.
		HiddenAPIFlagOutput: *output,
		hiddenAPIInfo.HiddenAPIFlagOutput = *output
	}

	//  Provide it for use by other modules.
	ctx.SetProvider(HiddenAPIInfoProvider, hiddenAPIInfo)

	return output
+37 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import (

	"android/soong/android"
	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"
)

// Contains support for processing hiddenAPI in a modular fashion.
@@ -395,6 +396,42 @@ func newHiddenAPIFlagInput() HiddenAPIFlagInput {
	return input
}

// canPerformHiddenAPIProcessing determines whether hidden API processing should be performed.
//
// A temporary workaround to avoid existing bootclasspath_fragments that do not provide the
// appropriate information needed for hidden API processing breaking the build.
// TODO(b/179354495): Remove this workaround.
func (i *HiddenAPIFlagInput) canPerformHiddenAPIProcessing(ctx android.ModuleContext, properties bootclasspathFragmentProperties) bool {
	// Performing hidden API processing without stubs is not supported and it is unlikely to ever be
	// required as the whole point of adding something to the bootclasspath fragment is to add it to
	// the bootclasspath in order to be used by something else in the system. Without any stubs it
	// cannot do that.
	if len(i.StubDexJarsByKind) == 0 {
		return false
	}

	// Hidden API processing is always enabled in tests.
	if ctx.Config().TestProductVariables != nil {
		return true
	}

	// A module that has fragments should have access to the information it needs in order to perform
	// hidden API processing.
	if len(properties.Fragments) != 0 {
		return true
	}

	// The art bootclasspath fragment does not depend on any other fragments but already supports
	// hidden API processing.
	imageName := proptools.String(properties.Image_name)
	if imageName == "art" {
		return true
	}

	// Disable it for everything else.
	return false
}

// gatherStubLibInfo gathers information from the stub libs needed by hidden API processing from the
// dependencies added in hiddenAPIAddStubLibDependencies.
//
+16 −5
Original line number Diff line number Diff line
@@ -70,11 +70,22 @@ func newMonolithicHiddenAPIInfo(ctx android.ModuleContext, flagFilesByCategory F
// append appends all the files from the supplied info to the corresponding files in this struct.
func (i *MonolithicHiddenAPIInfo) append(other *HiddenAPIInfo) {
	i.FlagsFilesByCategory.append(other.FlagFilesByCategory)
	i.StubFlagsPaths = append(i.StubFlagsPaths, other.StubFlagsPath)
	i.AnnotationFlagsPaths = append(i.AnnotationFlagsPaths, other.AnnotationFlagsPath)
	i.MetadataPaths = append(i.MetadataPaths, other.MetadataPath)
	i.IndexPaths = append(i.IndexPaths, other.IndexPath)
	i.AllFlagsPaths = append(i.AllFlagsPaths, other.AllFlagsPath)

	// The output may not be set if the bootclasspath_fragment has not yet been updated to support
	// hidden API processing.
	// TODO(b/179354495): Switch back to append once all bootclasspath_fragment modules have been
	//  updated to support hidden API processing properly.
	appendIfNotNil := func(paths android.Paths, path android.Path) android.Paths {
		if path == nil {
			return paths
		}
		return append(paths, path)
	}
	i.StubFlagsPaths = appendIfNotNil(i.StubFlagsPaths, other.StubFlagsPath)
	i.AnnotationFlagsPaths = appendIfNotNil(i.AnnotationFlagsPaths, other.AnnotationFlagsPath)
	i.MetadataPaths = appendIfNotNil(i.MetadataPaths, other.MetadataPath)
	i.IndexPaths = appendIfNotNil(i.IndexPaths, other.IndexPath)
	i.AllFlagsPaths = appendIfNotNil(i.AllFlagsPaths, other.AllFlagsPath)
}

// dedup removes duplicates in all the paths, while maintaining the order in which they were