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

Commit 438eb57a authored by Paul Duffin's avatar Paul Duffin
Browse files

Separate monolithic hidden API processing from hiddenAPIFlagFileInfo

The hiddenAPIFlagFileInfo was being used for both the input and output
of bootclasspath_fragment and platform_bootclasspath and also to pass
information around to various hidden API rule methods. Supporting
multiple different uses in this way made it hard to reason about.

This change creates a separate structure for use by the
platform_bootclasspath. Follow up changes will split out other
functionality into separate types.

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: Ia5c5f65ae5645486c42819c669a8601588217f88
parent c1cc3b96
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",
+2 −2
Original line number Diff line number Diff line
@@ -651,7 +651,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
@@ -689,7 +689,7 @@ func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx andro
	// Get the flag file information from the module.
	mctx := ctx.SdkModuleContext()
	flagFileInfo := mctx.OtherModuleProvider(module, hiddenAPIFlagFileInfoProvider).(hiddenAPIFlagFileInfo)
	b.Flag_files_by_category = flagFileInfo.categoryToPaths
	b.Flag_files_by_category = flagFileInfo.FlagFilesByCategory

	// Copy all the generated file paths.
	b.Stub_flags_path = pathsToOptionalPath(flagFileInfo.StubFlagsPaths)
+27 −20
Original line number Diff line number Diff line
@@ -261,10 +261,10 @@ type HiddenAPIFlagFileProperties struct {
}

func (p *HiddenAPIFlagFileProperties) hiddenAPIFlagFileInfo(ctx android.ModuleContext) hiddenAPIFlagFileInfo {
	info := hiddenAPIFlagFileInfo{categoryToPaths: map[*hiddenAPIFlagFileCategory]android.Paths{}}
	info := hiddenAPIFlagFileInfo{FlagFilesByCategory: FlagFilesByCategory{}}
	for _, category := range hiddenAPIFlagFileCategories {
		paths := android.PathsForModuleSrc(ctx, category.propertyValueReader(p))
		info.categoryToPaths[category] = paths
		info.FlagFilesByCategory[category] = paths
	}
	return info
}
@@ -365,6 +365,24 @@ var hiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
	},
}

// FlagFilesByCategory maps a hiddenAPIFlagFileCategory to the paths to the files in that category.
type FlagFilesByCategory map[*hiddenAPIFlagFileCategory]android.Paths

// append appends the supplied flags files to the corresponding category in this map.
func (s FlagFilesByCategory) append(other FlagFilesByCategory) {
	for _, category := range hiddenAPIFlagFileCategories {
		s[category] = append(s[category], other[category]...)
	}
}

// dedup removes duplicates in the flag files, while maintaining the order in which they were
// appended.
func (s FlagFilesByCategory) dedup() {
	for category, paths := range s {
		s[category] = android.FirstUniquePaths(paths)
	}
}

// hiddenAPIFlagFileInfo contains paths resolved from HiddenAPIFlagFileProperties and also generated
// by hidden API processing.
//
@@ -372,9 +390,9 @@ var hiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
// for a module to collate the files from the fragments it depends upon. That is why the fields are
// all Paths even though they are initialized with a single path.
type hiddenAPIFlagFileInfo struct {
	// categoryToPaths maps from the flag file category to the paths containing information for that
	// category.
	categoryToPaths map[*hiddenAPIFlagFileCategory]android.Paths
	// FlagFilesByCategory maps from the flag file category to the paths containing information for
	// that category.
	FlagFilesByCategory FlagFilesByCategory

	// The paths to the generated stub-flags.csv files.
	StubFlagsPaths android.Paths
@@ -392,17 +410,6 @@ type hiddenAPIFlagFileInfo struct {
	AllFlagsPaths android.Paths
}

func (i *hiddenAPIFlagFileInfo) append(other hiddenAPIFlagFileInfo) {
	for _, category := range hiddenAPIFlagFileCategories {
		i.categoryToPaths[category] = append(i.categoryToPaths[category], other.categoryToPaths[category]...)
	}
	i.StubFlagsPaths = append(i.StubFlagsPaths, other.StubFlagsPaths...)
	i.AnnotationFlagsPaths = append(i.AnnotationFlagsPaths, other.AnnotationFlagsPaths...)
	i.MetadataPaths = append(i.MetadataPaths, other.MetadataPaths...)
	i.IndexPaths = append(i.IndexPaths, other.IndexPaths...)
	i.AllFlagsPaths = append(i.AllFlagsPaths, other.AllFlagsPaths...)
}

var hiddenAPIFlagFileInfoProvider = blueprint.NewProvider(hiddenAPIFlagFileInfo{})

// pathForValidation creates a path of the same type as the supplied type but with a name of
@@ -428,14 +435,14 @@ func pathForValidation(ctx android.PathContext, path android.WritablePath) andro
//
// flagFileInfo is a struct containing paths to files that augment the information provided by
// the annotationFlags.
func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, baseFlagsPath android.Path, annotationFlags android.Path, flagFileInfo *hiddenAPIFlagFileInfo) {
func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, baseFlagsPath android.Path, annotationFlags android.Path, flagFilesByCategory FlagFilesByCategory, allFlagsPaths android.Paths) {

	// The file which is used to record that the flags file is valid.
	var validFile android.WritablePath

	// If there are flag files that have been generated by fragments on which this depends then use
	// them to validate the flag file generated by the rules created by this method.
	if allFlagsPaths := flagFileInfo.AllFlagsPaths; len(allFlagsPaths) > 0 {
	if len(allFlagsPaths) > 0 {
		// The flags file generated by the rule created by this method needs to be validated to ensure
		// that it is consistent with the flag files generated by the individual fragments.

@@ -463,7 +470,7 @@ func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc st

	// Add the options for the different categories of flag files.
	for _, category := range hiddenAPIFlagFileCategories {
		paths := flagFileInfo.categoryToPaths[category]
		paths := flagFilesByCategory[category]
		for _, path := range paths {
			category.commandMutator(command, path)
		}
@@ -530,7 +537,7 @@ func hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx android.ModuleContext
	// Generate the all-flags.csv which are the flags that will, in future, be encoded into the dex
	// files.
	outputPath := android.PathForModuleOut(ctx, hiddenApiSubDir, "all-flags.csv")
	buildRuleToGenerateHiddenApiFlags(ctx, "modularHiddenApiAllFlags", "modular hiddenapi all flags", outputPath, stubFlagsCSV, annotationFlagsCSV, flagFileInfo)
	buildRuleToGenerateHiddenApiFlags(ctx, "modularHiddenApiAllFlags", "modular hiddenapi all flags", outputPath, stubFlagsCSV, annotationFlagsCSV, flagFileInfo.FlagFilesByCategory, nil)

	// Store the paths in the info for use by other modules and sdk snapshot generation.
	flagFileInfo.StubFlagsPaths = android.Paths{stubFlagsCSV}
+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, hiddenAPIFlagFileInfoProvider) {
			info := ctx.OtherModuleProvider(fragment, hiddenAPIFlagFileInfoProvider).(hiddenAPIFlagFileInfo)
			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 *hiddenAPIFlagFileInfo) {
	i.FlagsFilesByCategory.append(other.FlagFilesByCategory)
	i.StubFlagsPaths = append(i.StubFlagsPaths, other.StubFlagsPaths...)
	i.AnnotationFlagsPaths = append(i.AnnotationFlagsPaths, other.AnnotationFlagsPaths...)
	i.MetadataPaths = append(i.MetadataPaths, other.MetadataPaths...)
	i.IndexPaths = append(i.IndexPaths, other.IndexPaths...)
	i.AllFlagsPaths = append(i.AllFlagsPaths, other.AllFlagsPaths...)
}

// 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{})
+14 −12
Original line number Diff line number Diff line
@@ -279,21 +279,12 @@ 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)
	sdkKindToStubPaths := hiddenAPIGatherStubLibDexJarPaths(ctx, nil)

	hiddenAPIModules := gatherHiddenAPIModuleFromContents(ctx, modules)

	sdkKindToStubPaths := hiddenAPIGatherStubLibDexJarPaths(ctx, nil)

	// Generate the monolithic stub-flags.csv file.
	bootDexJars := extractBootDexJarsFromHiddenAPIModules(ctx, hiddenAPIModules)
	stubFlags := hiddenAPISingletonPaths(ctx).stubFlags
@@ -309,7 +300,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 +319,17 @@ 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 {
	flagFileInfo := b.properties.Hidden_api.hiddenAPIFlagFileInfo(ctx)
	monolithicInfo := newMonolithicHiddenAPIInfo(ctx, flagFileInfo.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