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

Commit fa08e194 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I9f780b20,I53805737,I7373ba10,Ia5c5f65a into sc-dev

* changes:
  Rename hiddenAPIFlagFileInfo to HiddenAPIInfo
  Separate input to flag generation from hiddenAPIFlagFileInfo
  Separate output of flag generation from hiddenAPIFlagFileInfo
  Separate monolithic hidden API processing from hiddenAPIFlagFileInfo
parents acd45972 71955b4b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ bootstrap_go_package {
        "genrule.go",
        "hiddenapi.go",
        "hiddenapi_modular.go",
        "hiddenapi_monolithic.go",
        "hiddenapi_singleton.go",
        "jacoco.go",
        "java.go",
+67 −53
Original line number Diff line number Diff line
@@ -133,10 +133,12 @@ type BootclasspathFragmentModule struct {
type commonBootclasspathFragment interface {
	// produceHiddenAPIAllFlagsFile produces the all-flags.csv and intermediate files.
	//
	// Updates the supplied flagFileInfo with the paths to the generated files set.
	produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo)
	// Updates the supplied hiddenAPIInfo with the paths to the generated files set.
	produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, input HiddenAPIFlagInput) *HiddenAPIFlagOutput
}

var _ commonBootclasspathFragment = (*BootclasspathFragmentModule)(nil)

func bootclasspathFragmentFactory() android.Module {
	m := &BootclasspathFragmentModule{}
	m.AddProperties(&m.properties)
@@ -386,7 +388,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
	})

	// Perform hidden API processing.
	hiddenAPIInfo := b.generateHiddenAPIBuildActions(ctx, contents)
	hiddenAPIFlagOutput := 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.
@@ -395,20 +397,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, hiddenAPIInfo)
		b.provideApexContentInfo(ctx, imageConfig, contents, hiddenAPIFlagOutput)
	}
}

// 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, hiddenAPIInfo *hiddenAPIFlagFileInfo) {
func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, contents []android.Module, hiddenAPIFlagOutput *HiddenAPIFlagOutput) {
	// 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, hiddenAPIInfo)
	b.populateApexContentInfoDexJars(ctx, &info, contents, hiddenAPIFlagOutput)

	if !SkipDexpreoptBootJars(ctx) {
		// Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
@@ -425,12 +427,12 @@ 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, hiddenAPIInfo *hiddenAPIFlagFileInfo) {
func (b *BootclasspathFragmentModule) populateApexContentInfoDexJars(ctx android.ModuleContext, info *BootclasspathFragmentApexContentInfo, contents []android.Module, hiddenAPIFlagOutput *HiddenAPIFlagOutput) {

	info.contentModuleDexJarPaths = map[string]android.Path{}
	if hiddenAPIInfo != nil {
	if hiddenAPIFlagOutput != nil {
		// Hidden API encoding has been performed.
		flags := hiddenAPIInfo.AllFlagsPaths[0]
		flags := hiddenAPIFlagOutput.AllFlagsPath
		for _, m := range contents {
			h := m.(hiddenAPIModule)
			unencodedDex := h.bootDexJar()
@@ -527,7 +529,7 @@ 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) *hiddenAPIFlagFileInfo {
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.
@@ -536,42 +538,61 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.
		return nil
	}

	// Convert the kind specific lists of modules into kind specific lists of jars.
	stubJarsByKind := hiddenAPIGatherStubLibDexJarPaths(ctx, contents)
	// 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(stubJarsByKind) == 0 {
	if len(input.StubDexJarsByKind) == 0 {
		return nil
	}

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

	// Resolve the properties to paths.
	flagFileInfo := b.properties.Hidden_api.hiddenAPIFlagFileInfo(ctx)

	hiddenAPIModules := gatherHiddenAPIModuleFromContents(ctx, contents)

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

	// Initialize a HiddenAPIInfo structure and provide it for use by other modules.
	hiddenAPIInfo := HiddenAPIInfo{
		// The monolithic hidden API processing needs access to the flag files from all the fragments.
		FlagFilesByCategory: input.FlagFilesByCategory,

		// The monolithic hidden API processing also needs access to all the output files produced by
		// hidden API processing of this fragment.
		HiddenAPIFlagOutput: *output,
	}
	ctx.SetProvider(HiddenAPIInfoProvider, hiddenAPIInfo)

	return output
}

	// Store the information for use by platform_bootclasspath.
	ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo)
// createHiddenAPIFlagInput creates a HiddenAPIFlagInput struct and initializes it with information derived
// from the properties on this module and its dependencies.
func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.ModuleContext, contents []android.Module) HiddenAPIFlagInput {
	input := newHiddenAPIFlagInput()

	return &flagFileInfo
	// Update the input structure with information obtained from the stub libraries.
	input.gatherStubLibInfo(ctx, contents)

	// Populate with flag file paths from the properties.
	input.extractFlagFilesFromProperties(ctx, &b.properties.Hidden_api)

	return input
}

// produceHiddenAPIAllFlagsFile produces the hidden API all-flags.csv file (and supporting files)
// for the fragment.
func (b *BootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
	// Generate the rules to create the hidden API flags and update the supplied flagFileInfo with the
func (b *BootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, input HiddenAPIFlagInput) *HiddenAPIFlagOutput {
	// Generate the rules to create the hidden API flags and update the supplied hiddenAPIInfo with the
	// paths to the created files.
	hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx, contents, stubJarsByKind, flagFileInfo)
	return hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx, contents, input)
}

// generateBootImageBuildActions generates ninja rules to create the boot image if required for this
@@ -651,7 +672,7 @@ type bootclasspathFragmentSdkMemberProperties struct {
	Core_platform_stub_libs []string

	// Flag files by *hiddenAPIFlagFileCategory
	Flag_files_by_category map[*hiddenAPIFlagFileCategory]android.Paths
	Flag_files_by_category FlagFilesByCategory

	// The path to the generated stub-flags.csv file.
	Stub_flags_path android.OptionalPath
@@ -669,34 +690,23 @@ type bootclasspathFragmentSdkMemberProperties struct {
	All_flags_path android.OptionalPath
}

func pathsToOptionalPath(paths android.Paths) android.OptionalPath {
	switch len(paths) {
	case 0:
		return android.OptionalPath{}
	case 1:
		return android.OptionalPathForPath(paths[0])
	default:
		panic(fmt.Errorf("expected 0 or 1 paths, found %q", paths))
	}
}

func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
	module := variant.(*BootclasspathFragmentModule)

	b.Image_name = module.properties.Image_name
	b.Contents = module.properties.Contents

	// Get the flag file information from the module.
	// Get the hidden API information from the module.
	mctx := ctx.SdkModuleContext()
	flagFileInfo := mctx.OtherModuleProvider(module, hiddenAPIFlagFileInfoProvider).(hiddenAPIFlagFileInfo)
	b.Flag_files_by_category = flagFileInfo.categoryToPaths
	hiddenAPIInfo := mctx.OtherModuleProvider(module, HiddenAPIInfoProvider).(HiddenAPIInfo)
	b.Flag_files_by_category = hiddenAPIInfo.FlagFilesByCategory

	// Copy all the generated file paths.
	b.Stub_flags_path = pathsToOptionalPath(flagFileInfo.StubFlagsPaths)
	b.Annotation_flags_path = pathsToOptionalPath(flagFileInfo.AnnotationFlagsPaths)
	b.Metadata_path = pathsToOptionalPath(flagFileInfo.MetadataPaths)
	b.Index_path = pathsToOptionalPath(flagFileInfo.IndexPaths)
	b.All_flags_path = pathsToOptionalPath(flagFileInfo.AllFlagsPaths)
	b.Stub_flags_path = android.OptionalPathForPath(hiddenAPIInfo.StubFlagsPath)
	b.Annotation_flags_path = android.OptionalPathForPath(hiddenAPIInfo.AnnotationFlagsPath)
	b.Metadata_path = android.OptionalPathForPath(hiddenAPIInfo.MetadataPath)
	b.Index_path = android.OptionalPathForPath(hiddenAPIInfo.IndexPath)
	b.All_flags_path = android.OptionalPathForPath(hiddenAPIInfo.AllFlagsPath)

	// Copy stub_libs properties.
	b.Stub_libs = module.properties.Api.Stub_libs
@@ -806,20 +816,24 @@ func (module *prebuiltBootclasspathFragmentModule) Name() string {

// produceHiddenAPIAllFlagsFile returns a path to the prebuilt all-flags.csv or nil if none is
// specified.
func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
	pathsForOptionalSrc := func(src *string) android.Paths {
func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, _ HiddenAPIFlagInput) *HiddenAPIFlagOutput {
	pathForOptionalSrc := func(src *string) android.Path {
		if src == nil {
			// TODO(b/179354495): Fail if this is not provided once prebuilts have been updated.
			return nil
		}
		return android.Paths{android.PathForModuleSrc(ctx, *src)}
		return android.PathForModuleSrc(ctx, *src)
	}

	output := HiddenAPIFlagOutput{
		StubFlagsPath:       pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Stub_flags),
		AnnotationFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Annotation_flags),
		MetadataPath:        pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Metadata),
		IndexPath:           pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Index),
		AllFlagsPath:        pathForOptionalSrc(module.prebuiltProperties.Hidden_api.All_flags),
	}

	flagFileInfo.StubFlagsPaths = pathsForOptionalSrc(module.prebuiltProperties.Hidden_api.Stub_flags)
	flagFileInfo.AnnotationFlagsPaths = pathsForOptionalSrc(module.prebuiltProperties.Hidden_api.Annotation_flags)
	flagFileInfo.MetadataPaths = pathsForOptionalSrc(module.prebuiltProperties.Hidden_api.Metadata)
	flagFileInfo.IndexPaths = pathsForOptionalSrc(module.prebuiltProperties.Hidden_api.Index)
	flagFileInfo.AllFlagsPaths = pathsForOptionalSrc(module.prebuiltProperties.Hidden_api.All_flags)
	return &output
}

var _ commonBootclasspathFragment = (*prebuiltBootclasspathFragmentModule)(nil)
+147 −88

File changed.

Preview size limit exceeded, changes collapsed.

+91 −0
Original line number Diff line number Diff line
// Copyright (C) 2021 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package java

import (
	"android/soong/android"
	"github.com/google/blueprint"
)

// MonolithicHiddenAPIInfo contains information needed/provided by the hidden API generation of the
// monolithic hidden API files.
//
// Each list of paths includes all the equivalent paths from each of the bootclasspath_fragment
// modules that contribute to the platform-bootclasspath.
type MonolithicHiddenAPIInfo struct {
	// FlagsFilesByCategory maps from the flag file category to the paths containing information for
	// that category.
	FlagsFilesByCategory FlagFilesByCategory

	// The paths to the generated stub-flags.csv files.
	StubFlagsPaths android.Paths

	// The paths to the generated annotation-flags.csv files.
	AnnotationFlagsPaths android.Paths

	// The paths to the generated metadata.csv files.
	MetadataPaths android.Paths

	// The paths to the generated index.csv files.
	IndexPaths android.Paths

	// The paths to the generated all-flags.csv files.
	AllFlagsPaths android.Paths
}

// newMonolithicHiddenAPIInfo creates a new MonolithicHiddenAPIInfo from the flagFilesByCategory
// plus information provided by each of the fragments.
func newMonolithicHiddenAPIInfo(ctx android.ModuleContext, flagFilesByCategory FlagFilesByCategory, fragments []android.Module) MonolithicHiddenAPIInfo {
	monolithicInfo := MonolithicHiddenAPIInfo{}

	monolithicInfo.FlagsFilesByCategory = flagFilesByCategory

	// Merge all the information from the fragments. The fragments form a DAG so it is possible that
	// this will introduce duplicates so they will be resolved after processing all the fragments.
	for _, fragment := range fragments {
		if ctx.OtherModuleHasProvider(fragment, HiddenAPIInfoProvider) {
			info := ctx.OtherModuleProvider(fragment, HiddenAPIInfoProvider).(HiddenAPIInfo)
			monolithicInfo.append(&info)
		}
	}

	// Dedup paths.
	monolithicInfo.dedup()

	return monolithicInfo
}

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

// dedup removes duplicates in all the paths, while maintaining the order in which they were
// appended.
func (i *MonolithicHiddenAPIInfo) dedup() {
	i.FlagsFilesByCategory.dedup()
	i.StubFlagsPaths = android.FirstUniquePaths(i.StubFlagsPaths)
	i.AnnotationFlagsPaths = android.FirstUniquePaths(i.AnnotationFlagsPaths)
	i.MetadataPaths = android.FirstUniquePaths(i.MetadataPaths)
	i.IndexPaths = android.FirstUniquePaths(i.IndexPaths)
	i.AllFlagsPaths = android.FirstUniquePaths(i.AllFlagsPaths)
}

var monolithicHiddenAPIInfoProvider = blueprint.NewProvider(MonolithicHiddenAPIInfo{})
+31 −13
Original line number Diff line number Diff line
@@ -279,25 +279,24 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.
		return
	}

	flagFileInfo := b.properties.Hidden_api.hiddenAPIFlagFileInfo(ctx)
	for _, fragment := range fragments {
		if ctx.OtherModuleHasProvider(fragment, hiddenAPIFlagFileInfoProvider) {
			info := ctx.OtherModuleProvider(fragment, hiddenAPIFlagFileInfoProvider).(hiddenAPIFlagFileInfo)
			flagFileInfo.append(info)
		}
	}
	monolithicInfo := b.createAndProvideMonolithicHiddenAPIInfo(ctx, fragments)

	// Store the information for testing.
	ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo)
	// Create the input to pass to ruleToGenerateHiddenAPIStubFlagsFile
	input := newHiddenAPIFlagInput()

	hiddenAPIModules := gatherHiddenAPIModuleFromContents(ctx, modules)
	// Gather stub library information from the dependencies on modules provided by
	// hiddenAPIComputeMonolithicStubLibModules.
	input.gatherStubLibInfo(ctx, nil)

	// Use the flag files from this module and all the fragments.
	input.FlagFilesByCategory = monolithicInfo.FlagsFilesByCategory

	sdkKindToStubPaths := hiddenAPIGatherStubLibDexJarPaths(ctx, nil)
	hiddenAPIModules := gatherHiddenAPIModuleFromContents(ctx, modules)

	// Generate the monolithic stub-flags.csv file.
	bootDexJars := extractBootDexJarsFromHiddenAPIModules(ctx, hiddenAPIModules)
	stubFlags := hiddenAPISingletonPaths(ctx).stubFlags
	rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlags, bootDexJars, sdkKindToStubPaths)
	rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlags, bootDexJars, input)
	rule.Build("platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags")

	// Extract the classes jars from the contents.
@@ -309,7 +308,7 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.

	// Generate the monotlithic hiddenapi-flags.csv file.
	allFlags := hiddenAPISingletonPaths(ctx).flags
	buildRuleToGenerateHiddenApiFlags(ctx, "hiddenAPIFlagsFile", "hiddenapi flags", allFlags, stubFlags, annotationFlags, &flagFileInfo)
	buildRuleToGenerateHiddenApiFlags(ctx, "hiddenAPIFlagsFile", "hiddenapi flags", allFlags, stubFlags, annotationFlags, monolithicInfo.FlagsFilesByCategory, monolithicInfo.AllFlagsPaths)

	// Generate an intermediate monolithic hiddenapi-metadata.csv file directly from the annotations
	// in the source code.
@@ -328,6 +327,25 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.
	buildRuleToGenerateIndex(ctx, "monolithic hidden API index", classesJars, indexCSV)
}

// createAndProvideMonolithicHiddenAPIInfo creates a MonolithicHiddenAPIInfo and provides it for
// testing.
func (b *platformBootclasspathModule) createAndProvideMonolithicHiddenAPIInfo(ctx android.ModuleContext, fragments []android.Module) MonolithicHiddenAPIInfo {
	// Create a temporary input structure in which to collate information provided directly by this
	// module, either through properties or direct dependencies.
	temporaryInput := newHiddenAPIFlagInput()

	// Create paths to the flag files specified in the properties.
	temporaryInput.extractFlagFilesFromProperties(ctx, &b.properties.Hidden_api)

	// Create the monolithic info, by starting with the flag files specified on this and then merging
	// in information from all the fragment dependencies of this.
	monolithicInfo := newMonolithicHiddenAPIInfo(ctx, temporaryInput.FlagFilesByCategory, fragments)

	// Store the information for testing.
	ctx.SetProvider(monolithicHiddenAPIInfoProvider, monolithicInfo)
	return monolithicInfo
}

func (b *platformBootclasspathModule) buildRuleMergeCSV(ctx android.ModuleContext, desc string, inputPaths android.Paths, outputPath android.WritablePath) {
	rule := android.NewRuleBuilder(pctx, ctx)
	rule.Command().
Loading