Merge "Define a narrower context for getting arch props"
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 922e40a..68182a7 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -4542,7 +4542,12 @@
}
func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
- preparer := java.FixtureConfigureBootJars("myapex:libfoo", "myapex:libbar")
+ preparer := android.GroupFixturePreparers(
+ java.FixtureConfigureBootJars("myapex:libfoo", "myapex:libbar"),
+ // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
+ // is disabled.
+ android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
+ )
checkBootDexJarPath := func(t *testing.T, ctx *android.TestContext, stem string, bootDexJarPath string) {
t.Helper()
@@ -4564,7 +4569,7 @@
checkHiddenAPIIndexInputs := func(t *testing.T, ctx *android.TestContext, expectedInputs string) {
t.Helper()
platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common")
- indexRule := platformBootclasspath.Rule("platform-bootclasspath-monolithic-hiddenapi-index")
+ indexRule := platformBootclasspath.Rule("monolithic_hidden_API_index")
java.CheckHiddenAPIRuleInputs(t, expectedInputs, indexRule)
}
@@ -4602,10 +4607,10 @@
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
- // Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
+ // Verify the correct module jars contribute to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
-.intermediates/libbar/android_common_myapex/hiddenapi/index.csv
-.intermediates/libfoo/android_common_myapex/hiddenapi/index.csv
+.intermediates/libbar.stubs/android_common/combined/libbar.stubs.jar
+.intermediates/libfoo/android_common_myapex/combined/libfoo.jar
`)
})
@@ -4636,10 +4641,10 @@
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
- // Make sure that the dex file from the apex_set contributes to the hiddenapi index file.
+ // Verify the correct module jars contribute to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
-.intermediates/libbar/android_common_myapex/hiddenapi/index.csv
-.intermediates/libfoo/android_common_myapex/hiddenapi/index.csv
+.intermediates/libbar.stubs/android_common/combined/libbar.stubs.jar
+.intermediates/libfoo/android_common_myapex/combined/libfoo.jar
`)
})
@@ -4743,10 +4748,10 @@
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
- // Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
+ // Verify the correct module jars contribute to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
-.intermediates/prebuilt_libbar/android_common_myapex/hiddenapi/index.csv
-.intermediates/prebuilt_libfoo/android_common_myapex/hiddenapi/index.csv
+.intermediates/prebuilt_libbar.stubs/android_common/combined/libbar.stubs.jar
+.intermediates/prebuilt_libfoo/android_common_myapex/combined/libfoo.jar
`)
})
@@ -4810,10 +4815,10 @@
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/libfoo/android_common_apex10000/hiddenapi/libfoo.jar")
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/libbar/android_common_myapex/hiddenapi/libbar.jar")
- // Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
+ // Verify the correct module jars contribute to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
-.intermediates/libbar/android_common_myapex/hiddenapi/index.csv
-.intermediates/libfoo/android_common_apex10000/hiddenapi/index.csv
+.intermediates/libbar/android_common_myapex/javac/libbar.jar
+.intermediates/libfoo/android_common_apex10000/javac/libfoo.jar
`)
})
@@ -4879,10 +4884,10 @@
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
- // Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
+ // Verify the correct module jars contribute to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
-.intermediates/prebuilt_libbar/android_common_myapex/hiddenapi/index.csv
-.intermediates/prebuilt_libfoo/android_common_myapex/hiddenapi/index.csv
+.intermediates/prebuilt_libbar.stubs/android_common/combined/libbar.stubs.jar
+.intermediates/prebuilt_libfoo/android_common_myapex/combined/libfoo.jar
`)
})
}
diff --git a/java/base.go b/java/base.go
index 2cc0e76..03652be 100644
--- a/java/base.go
+++ b/java/base.go
@@ -1223,9 +1223,11 @@
return
}
- // Hidden API CSV generation and dex encoding
- dexOutputFile = j.hiddenAPIExtractAndEncode(ctx, dexOutputFile, j.implementationJarFile,
- proptools.Bool(j.dexProperties.Uncompress_dex))
+ // Update hidden API paths.
+ j.hiddenAPIUpdatePaths(ctx, dexOutputFile, j.implementationJarFile)
+
+ // Encode hidden API flags in dex file.
+ dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile, proptools.Bool(j.dexProperties.Uncompress_dex))
// merge dex jar with resources if necessary
if j.resourceJar != nil {
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 68a7ad2..16aa5e2 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -129,7 +129,7 @@
// 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 []android.Module, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo)
+ produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo)
}
func bootclasspathFragmentFactory() android.Module {
@@ -461,9 +461,11 @@
// 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.
common := ctx.Module().(commonBootclasspathFragment)
- common.produceHiddenAPIAllFlagsFile(ctx, contents, stubJarsByKind, &flagFileInfo)
+ common.produceHiddenAPIAllFlagsFile(ctx, hiddenAPIModules, stubJarsByKind, &flagFileInfo)
// Store the information for use by platform_bootclasspath.
ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo)
@@ -471,7 +473,7 @@
// produceHiddenAPIAllFlagsFile produces the hidden API all-flags.csv file (and supporting files)
// for the fragment.
-func (b *BootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []android.Module, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
+func (b *BootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
// If no stubs have been provided then don't perform hidden API processing. This is a temporary
// workaround to avoid existing bootclasspath_fragments that do not provide stubs breaking the
// build.
@@ -718,7 +720,7 @@
// produceHiddenAPIAllFlagsFile returns a path to the prebuilt all-flags.csv or nil if none is
// specified.
-func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, _ []android.Module, _ map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
+func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
pathsForOptionalSrc := func(src *string) android.Paths {
if src == nil {
// TODO(b/179354495): Fail if this is not provided once prebuilts have been updated.
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index ea2a851..829c473 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -56,66 +56,28 @@
// this file so using the encoded dex jar here would result in a cycle in the ninja rules.
bootDexJarPath android.Path
- // The path to the CSV file that contains mappings from Java signature to various flags derived
- // from annotations in the source, e.g. whether it is public or the sdk version above which it
- // can no longer be used.
- //
- // It is created by the Class2NonSdkList tool which processes the .class files in the class
- // implementation jar looking for UnsupportedAppUsage and CovariantReturnType annotations. The
- // tool also consumes the hiddenAPISingletonPathsStruct.stubFlags file in order to perform
- // consistency checks on the information in the annotations and to filter out bridge methods
- // that are already part of the public API.
- flagsCSVPath android.Path
-
- // The path to the CSV file that contains mappings from Java signature to the value of properties
- // specified on UnsupportedAppUsage annotations in the source.
- //
- // Like the flagsCSVPath file this is also created by the Class2NonSdkList in the same way.
- // Although the two files could potentially be created in a single invocation of the
- // Class2NonSdkList at the moment they are created using their own invocation, with the behavior
- // being determined by the property that is used.
- metadataCSVPath android.Path
-
- // The path to the CSV file that contains mappings from Java signature to source location
- // information.
- //
- // It is created by the merge_csv tool which processes the class implementation jar, extracting
- // all the files ending in .uau (which are CSV files) and merges them together. The .uau files are
- // created by the unsupported app usage annotation processor during compilation of the class
- // implementation jar.
- indexCSVPath android.Path
-
// The paths to the classes jars that contain classes and class members annotated with
// the UnsupportedAppUsage annotation that need to be extracted as part of the hidden API
// processing.
classesJarPaths android.Paths
}
-func (h *hiddenAPI) flagsCSV() android.Path {
- return h.flagsCSVPath
-}
-
-func (h *hiddenAPI) metadataCSV() android.Path {
- return h.metadataCSVPath
-}
-
func (h *hiddenAPI) bootDexJar() android.Path {
return h.bootDexJarPath
}
-func (h *hiddenAPI) indexCSV() android.Path {
- return h.indexCSVPath
-}
-
func (h *hiddenAPI) classesJars() android.Paths {
return h.classesJarPaths
}
+// hiddenAPIModule is the interface a module that embeds the hiddenAPI structure must implement.
+type hiddenAPIModule interface {
+ android.Module
+ hiddenAPIIntf
+}
+
type hiddenAPIIntf interface {
bootDexJar() android.Path
- flagsCSV() android.Path
- indexCSV() android.Path
- metadataCSV() android.Path
classesJars() android.Paths
}
@@ -130,6 +92,12 @@
h.configurationName = configurationName
+ // If the frameworks/base directories does not exist and no prebuilt hidden API flag files have
+ // been configured then it is not possible to do hidden API encoding.
+ if !ctx.Config().FrameworksBaseDirExists(ctx) && ctx.Config().PrebuiltHiddenApiDir(ctx) == "" {
+ return
+ }
+
// It is important that hiddenapi information is only gathered for/from modules that are actually
// on the boot jars list because the runtime only enforces access to the hidden API for the
// bootclassloader. If information is gathered for modules not on the list then that will cause
@@ -191,25 +159,14 @@
return active
}
-// hiddenAPIExtractAndEncode is called by any module that could contribute to the hiddenapi
-// processing.
+// hiddenAPIEncodeDex is called by any module that needs to encode dex files.
//
// It ignores any module that has not had initHiddenApi() called on it and which is not in the boot
-// jar list.
+// jar list. In that case it simply returns the supplied dex jar path.
//
-// Otherwise, it generates ninja rules to do the following:
-// 1. Extract information needed for hiddenapi processing from the module and output it into CSV
-// files.
-// 2. Conditionally adds the supplied dex file to the list of files used to generate the
-// hiddenAPISingletonPathsStruct.stubsFlag file.
-// 3. Conditionally creates a copy of the supplied dex file into which it has encoded the hiddenapi
-// flags and returns this instead of the supplied dex jar, otherwise simply returns the supplied
-// dex jar.
-func (h *hiddenAPI) hiddenAPIExtractAndEncode(ctx android.ModuleContext, dexJar android.OutputPath,
- implementationJar android.Path, uncompressDex bool) android.OutputPath {
-
- // Call before checking if this is active as it will update the hiddenAPI structure.
- h.hiddenAPIExtractInformation(ctx, dexJar, implementationJar)
+// Otherwise, it creates a copy of the supplied dex file into which it has encoded the hiddenapi
+// flags and returns this instead of the supplied dex jar.
+func (h *hiddenAPI) hiddenAPIEncodeDex(ctx android.ModuleContext, dexJar android.OutputPath, uncompressDex bool) android.OutputPath {
if !h.active {
return dexJar
@@ -226,12 +183,12 @@
return dexJar
}
-// hiddenAPIExtractInformation generates ninja rules to extract the information from the classes
+// hiddenAPIUpdatePaths generates ninja rules to extract the information from the classes
// jar, and outputs it to the appropriate module specific CSV file.
//
// It also makes the dex jar available for use when generating the
// hiddenAPISingletonPathsStruct.stubFlags.
-func (h *hiddenAPI) hiddenAPIExtractInformation(ctx android.ModuleContext, dexJar, classesJar android.Path) {
+func (h *hiddenAPI) hiddenAPIUpdatePaths(ctx android.ModuleContext, dexJar, classesJar android.Path) {
// Save the classes jars even if this is not active as they may be used by modular hidden API
// processing.
@@ -245,38 +202,48 @@
// Save the unencoded dex jar so it can be used when generating the
// hiddenAPISingletonPathsStruct.stubFlags file.
h.bootDexJarPath = dexJar
+}
- if !h.active {
- return
- }
-
- // More than one library with the same classes may need to be encoded but only one should be
- // used as a source of information for hidden API processing otherwise it will result in
- // duplicate entries in the files.
- if !h.primary {
- return
- }
-
- stubFlagsCSV := hiddenAPISingletonPaths(ctx).stubFlags
-
- flagsCSV := android.PathForModuleOut(ctx, "hiddenapi", "flags.csv")
+// buildRuleToGenerateAnnotationFlags builds a ninja rule to generate the annotation-flags.csv file
+// from the classes jars and stub-flags.csv files.
+//
+// The annotation-flags.csv file contains mappings from Java signature to various flags derived from
+// annotations in the source, e.g. whether it is public or the sdk version above which it can no
+// longer be used.
+//
+// It is created by the Class2NonSdkList tool which processes the .class files in the class
+// implementation jar looking for UnsupportedAppUsage and CovariantReturnType annotations. The
+// tool also consumes the hiddenAPISingletonPathsStruct.stubFlags file in order to perform
+// consistency checks on the information in the annotations and to filter out bridge methods
+// that are already part of the public API.
+func buildRuleToGenerateAnnotationFlags(ctx android.ModuleContext, desc string, classesJars android.Paths, stubFlagsCSV android.Path, outputPath android.WritablePath) {
ctx.Build(pctx, android.BuildParams{
Rule: hiddenAPIGenerateCSVRule,
- Description: "hiddenapi flags",
+ Description: desc,
Inputs: classesJars,
- Output: flagsCSV,
+ Output: outputPath,
Implicit: stubFlagsCSV,
Args: map[string]string{
"outFlag": "--write-flags-csv",
"stubAPIFlags": stubFlagsCSV.String(),
},
})
- h.flagsCSVPath = flagsCSV
+}
- metadataCSV := android.PathForModuleOut(ctx, "hiddenapi", "metadata.csv")
+// buildRuleToGenerateMetadata builds a ninja rule to generate the metadata.csv file from
+// the classes jars and stub-flags.csv files.
+//
+// The metadata.csv file contains mappings from Java signature to the value of properties specified
+// on UnsupportedAppUsage annotations in the source.
+//
+// Like the annotation-flags.csv file this is also created by the Class2NonSdkList in the same way.
+// Although the two files could potentially be created in a single invocation of the
+// Class2NonSdkList at the moment they are created using their own invocation, with the behavior
+// being determined by the property that is used.
+func buildRuleToGenerateMetadata(ctx android.ModuleContext, desc string, classesJars android.Paths, stubFlagsCSV android.Path, metadataCSV android.WritablePath) {
ctx.Build(pctx, android.BuildParams{
Rule: hiddenAPIGenerateCSVRule,
- Description: "hiddenapi metadata",
+ Description: desc,
Inputs: classesJars,
Output: metadataCSV,
Implicit: stubFlagsCSV,
@@ -285,18 +252,27 @@
"stubAPIFlags": stubFlagsCSV.String(),
},
})
- h.metadataCSVPath = metadataCSV
+}
- indexCSV := android.PathForModuleOut(ctx, "hiddenapi", "index.csv")
+// buildRuleToGenerateIndex builds a ninja rule to generate the index.csv file from the classes
+// jars.
+//
+// The index.csv file contains mappings from Java signature to source location information.
+//
+// It is created by the merge_csv tool which processes the class implementation jar, extracting
+// all the files ending in .uau (which are CSV files) and merges them together. The .uau files are
+// created by the unsupported app usage annotation processor during compilation of the class
+// implementation jar.
+func buildRuleToGenerateIndex(ctx android.ModuleContext, desc string, classesJars android.Paths, indexCSV android.WritablePath) {
rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().
BuiltTool("merge_csv").
Flag("--zip_input").
Flag("--key_field signature").
+ FlagWithArg("--header=", "signature,file,startline,startcol,endline,endcol,properties").
FlagWithOutput("--output=", indexCSV).
Inputs(classesJars)
- rule.Build("merged-hiddenapi-index", "Merged Hidden API index")
- h.indexCSVPath = indexCSV
+ rule.Build(desc, desc)
}
var hiddenAPIEncodeDexRule = pctx.AndroidStaticRule("hiddenAPIEncodeDex", blueprint.RuleParams{
@@ -333,11 +309,7 @@
}
enforceHiddenApiFlagsToAllMembers := true
- // If frameworks/base doesn't exist we must be building with the 'master-art' manifest.
- // Disable assertion that all methods/fields have hidden API flags assigned.
- if !ctx.Config().FrameworksBaseDirExists(ctx) {
- enforceHiddenApiFlagsToAllMembers = false
- }
+
// 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.
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index b3a3735..2dceb65 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -422,12 +422,12 @@
// an entry for every single member in the dex implementation jars of the individual modules. Every
// signature in any of the other files MUST be included in this file.
//
-// moduleSpecificFlagsPaths are the paths to the flags files generated by each module using
-// information from the baseFlagsPath as well as from annotations within the source.
+// annotationFlags is the path to the annotation flags file generated from annotation information
+// in each module.
//
-// augmentationInfo is a struct containing paths to files that augment the information provided by
-// the moduleSpecificFlagsPaths.
-func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, baseFlagsPath android.Path, moduleSpecificFlagsPaths android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
+// 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) {
// The file which is used to record that the flags file is valid.
var validFile android.WritablePath
@@ -457,7 +457,7 @@
command := rule.Command().
BuiltTool("generate_hiddenapi_lists").
FlagWithInput("--csv ", baseFlagsPath).
- Inputs(moduleSpecificFlagsPaths).
+ Input(annotationFlags).
FlagWithOutput("--output ", tempPath)
// Add the options for the different categories of flag files.
@@ -495,69 +495,29 @@
// * metadata.csv
// * index.csv
// * all-flags.csv
-func hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx android.ModuleContext, contents []android.Module, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
-
+func hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx android.ModuleContext, contents []hiddenAPIModule, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
hiddenApiSubDir := "modular-hiddenapi"
- bootDexJars := android.Paths{}
- classesJars := android.Paths{}
- for _, module := range contents {
- if hiddenAPI, ok := module.(hiddenAPIIntf); ok {
- classesJars = append(classesJars, hiddenAPI.classesJars()...)
- bootDexJar := hiddenAPI.bootDexJar()
- if bootDexJar == nil {
- ctx.ModuleErrorf("module %s does not provide a dex jar", module)
- } else {
- bootDexJars = append(bootDexJars, bootDexJar)
- }
- } else {
- ctx.ModuleErrorf("module %s does not implement hiddenAPIIntf", module)
- }
- }
-
// Generate the stub-flags.csv.
+ bootDexJars := extractBootDexJarsFromHiddenAPIModules(ctx, contents)
stubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "stub-flags.csv")
rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlagsCSV, bootDexJars, stubJarsByKind)
rule.Build("modularHiddenAPIStubFlagsFile", "modular hiddenapi stub flags")
+ // Extract the classes jars from the contents.
+ classesJars := extractClassJarsFromHiddenAPIModules(ctx, contents)
+
// Generate the set of flags from the annotations in the source code.
annotationFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "annotation-flags.csv")
- ctx.Build(pctx, android.BuildParams{
- Rule: hiddenAPIGenerateCSVRule,
- Description: "modular hiddenapi annotation flags",
- Inputs: classesJars,
- Output: annotationFlagsCSV,
- Implicit: stubFlagsCSV,
- Args: map[string]string{
- "outFlag": "--write-flags-csv",
- "stubAPIFlags": stubFlagsCSV.String(),
- },
- })
+ buildRuleToGenerateAnnotationFlags(ctx, "modular hiddenapi annotation flags", classesJars, stubFlagsCSV, annotationFlagsCSV)
// Generate the metadata from the annotations in the source code.
metadataCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "metadata.csv")
- ctx.Build(pctx, android.BuildParams{
- Rule: hiddenAPIGenerateCSVRule,
- Description: "modular hiddenapi metadata",
- Inputs: classesJars,
- Output: metadataCSV,
- Implicit: stubFlagsCSV,
- Args: map[string]string{
- "outFlag": "--write-metadata-csv",
- "stubAPIFlags": stubFlagsCSV.String(),
- },
- })
+ buildRuleToGenerateMetadata(ctx, "modular hiddenapi metadata", classesJars, stubFlagsCSV, metadataCSV)
- // Generate the index file from the annotations in the source code.
+ // Generate the index file from the CSV files in the classes jars.
indexCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "index.csv")
- rule = android.NewRuleBuilder(pctx, ctx)
- rule.Command().
- BuiltTool("merge_csv").
- Flag("--zip_input").
- Flag("--key_field signature").
- FlagWithOutput("--output=", indexCSV).
- Inputs(classesJars)
- rule.Build("modular-hiddenapi-index", "modular hiddenapi index")
+ buildRuleToGenerateIndex(ctx, "modular hiddenapi index", classesJars, indexCSV)
// Removed APIs need to be marked and in order to do that the flagFileInfo needs to specify files
// containing dex signatures of all the removed APIs. In the monolithic files that is done by
@@ -569,7 +529,7 @@
// 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, android.Paths{annotationFlagsCSV}, flagFileInfo)
+ buildRuleToGenerateHiddenApiFlags(ctx, "modularHiddenApiAllFlags", "modular hiddenapi all flags", outputPath, stubFlagsCSV, annotationFlagsCSV, flagFileInfo)
// Store the paths in the info for use by other modules and sdk snapshot generation.
flagFileInfo.StubFlagsPaths = android.Paths{stubFlagsCSV}
@@ -578,3 +538,41 @@
flagFileInfo.IndexPaths = android.Paths{indexCSV}
flagFileInfo.AllFlagsPaths = android.Paths{outputPath}
}
+
+// gatherHiddenAPIModuleFromContents gathers the hiddenAPIModule from the supplied contents.
+func gatherHiddenAPIModuleFromContents(ctx android.ModuleContext, contents []android.Module) []hiddenAPIModule {
+ hiddenAPIModules := []hiddenAPIModule{}
+ for _, module := range contents {
+ if hiddenAPI, ok := module.(hiddenAPIModule); ok {
+ hiddenAPIModules = append(hiddenAPIModules, hiddenAPI)
+ } else if _, ok := module.(*DexImport); ok {
+ // Ignore this for the purposes of hidden API processing
+ } else {
+ ctx.ModuleErrorf("module %s does not implement hiddenAPIModule", module)
+ }
+ }
+ return hiddenAPIModules
+}
+
+// extractBootDexJarsFromHiddenAPIModules extracts the boot dex jars from the supplied modules.
+func extractBootDexJarsFromHiddenAPIModules(ctx android.ModuleContext, contents []hiddenAPIModule) android.Paths {
+ bootDexJars := android.Paths{}
+ for _, module := range contents {
+ bootDexJar := module.bootDexJar()
+ if bootDexJar == nil {
+ ctx.ModuleErrorf("module %s does not provide a dex jar", module)
+ } else {
+ bootDexJars = append(bootDexJars, bootDexJar)
+ }
+ }
+ return bootDexJars
+}
+
+// extractClassJarsFromHiddenAPIModules extracts the class jars from the supplied modules.
+func extractClassJarsFromHiddenAPIModules(ctx android.ModuleContext, contents []hiddenAPIModule) android.Paths {
+ classesJars := android.Paths{}
+ for _, module := range contents {
+ classesJars = append(classesJars, module.classesJars()...)
+ }
+ return classesJars
+}
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 676a0e7..848aa59 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -117,7 +117,6 @@
}
type hiddenAPISingleton struct {
- flags android.Path
}
// hiddenAPI singleton rules
@@ -136,17 +135,10 @@
// consistency.
if ctx.Config().PrebuiltHiddenApiDir(ctx) != "" {
- h.flags = prebuiltFlagsRule(ctx)
+ prebuiltFlagsRule(ctx)
prebuiltIndexRule(ctx)
return
}
-
- // These rules depend on files located in frameworks/base, skip them if running in a tree that doesn't have them.
- if ctx.Config().FrameworksBaseDirExists(ctx) {
- h.flags = flagsRule(ctx)
- } else {
- h.flags = emptyFlagsRule(ctx)
- }
}
// Checks to see whether the supplied module variant is in the list of boot jars.
@@ -187,7 +179,7 @@
return true
}
-func prebuiltFlagsRule(ctx android.SingletonContext) android.Path {
+func prebuiltFlagsRule(ctx android.SingletonContext) {
outputPath := hiddenAPISingletonPaths(ctx).flags
inputPath := android.PathForSource(ctx, ctx.Config().PrebuiltHiddenApiDir(ctx), "hiddenapi-flags.csv")
@@ -196,8 +188,6 @@
Output: outputPath,
Input: inputPath,
})
-
- return outputPath
}
func prebuiltIndexRule(ctx android.SingletonContext) {
@@ -211,28 +201,6 @@
})
}
-// flagsRule is a placeholder that simply returns the location of the file, the generation of the
-// ninja rules is done in generateHiddenAPIBuildActions.
-func flagsRule(ctx android.SingletonContext) android.Path {
- outputPath := hiddenAPISingletonPaths(ctx).flags
- return outputPath
-}
-
-// emptyFlagsRule creates a rule to build an empty hiddenapi-flags.csv, which is needed by master-art-host builds that
-// have a partial manifest without frameworks/base but still need to build a boot image.
-func emptyFlagsRule(ctx android.SingletonContext) android.Path {
- rule := android.NewRuleBuilder(pctx, ctx)
-
- outputPath := hiddenAPISingletonPaths(ctx).flags
-
- rule.Command().Text("rm").Flag("-f").Output(outputPath)
- rule.Command().Text("touch").Output(outputPath)
-
- rule.Build("emptyHiddenAPIFlagsFile", "empty hiddenapi flags")
-
- return outputPath
-}
-
// tempPathForRestat creates a path of the same type as the supplied type but with a name of
// <path>.tmp.
//
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index 3ab2277..e6b45ac 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -60,10 +60,7 @@
}
func TestHiddenAPISingletonWithSourceAndPrebuiltPreferredButNoDex(t *testing.T) {
- expectedErrorMessage :=
- "hiddenapi has determined that the source module \"foo\" should be ignored as it has been" +
- " replaced by the prebuilt module \"prebuilt_foo\" but unfortunately it does not provide a" +
- " suitable boot dex jar"
+ expectedErrorMessage := "module prebuilt_foo{os:android,arch:common} does not provide a dex jar"
android.GroupFixturePreparers(
hiddenApiFixtureFactory,
diff --git a/java/java.go b/java/java.go
index 9a5fbfc..f85de3d 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1315,7 +1315,7 @@
di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo)
if dexOutputPath := di.PrebuiltExportPath(j.BaseModuleName(), ".dexjar"); dexOutputPath != nil {
j.dexJarFile = dexOutputPath
- j.hiddenAPIExtractInformation(ctx, dexOutputPath, outputFile)
+ j.hiddenAPIUpdatePaths(ctx, dexOutputPath, outputFile)
} else {
// This should never happen as a variant for a prebuilt_apex is only created if the
// prebuilt_apex has been configured to export the java library dex file.
@@ -1346,9 +1346,11 @@
return
}
- // Hidden API CSV generation and dex encoding
- dexOutputFile = j.hiddenAPIExtractAndEncode(ctx, dexOutputFile, outputFile,
- proptools.Bool(j.dexProperties.Uncompress_dex))
+ // Update hidden API paths.
+ j.hiddenAPIUpdatePaths(ctx, dexOutputFile, outputFile)
+
+ // Encode hidden API flags in dex file.
+ dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile, proptools.Bool(j.dexProperties.Uncompress_dex))
j.dexJarFile = dexOutputFile
}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 5880e2f..c8fafed 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -257,17 +257,6 @@
return defaultBootImageConfig(ctx)
}
-// hiddenAPISupportingModule encapsulates the information provided by any module that contributes to
-// the hidden API processing.
-type hiddenAPISupportingModule struct {
- module android.Module
-
- bootDexJar android.Path
- flagsCSV android.Path
- indexCSV android.Path
- metadataCSV android.Path
-}
-
// generateHiddenAPIBuildActions generates all the hidden API related build rules.
func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module, fragments []android.Module) {
@@ -290,67 +279,6 @@
return
}
- // nilPathHandler will check the supplied path and if it is nil then it will either immediately
- // report an error, or it will defer the error reporting until it is actually used, depending
- // whether missing dependencies are allowed.
- var nilPathHandler func(path android.Path, name string, module android.Module) android.Path
- if ctx.Config().AllowMissingDependencies() {
- nilPathHandler = func(path android.Path, name string, module android.Module) android.Path {
- if path == nil {
- outputPath := android.PathForModuleOut(ctx, "missing", module.Name(), name)
- path = outputPath
-
- // Create an error rule that pretends to create the output file but will actually fail if it
- // is run.
- ctx.Build(pctx, android.BuildParams{
- Rule: android.ErrorRule,
- Output: outputPath,
- Args: map[string]string{
- "error": fmt.Sprintf("missing hidden API file: %s for %s", name, module),
- },
- })
- }
- return path
- }
- } else {
- nilPathHandler = func(path android.Path, name string, module android.Module) android.Path {
- if path == nil {
- ctx.ModuleErrorf("module %s does not provide a %s file", module, name)
- }
- return path
- }
- }
-
- hiddenAPISupportingModules := []hiddenAPISupportingModule{}
- for _, module := range modules {
- if h, ok := module.(hiddenAPIIntf); ok {
- hiddenAPISupportingModule := hiddenAPISupportingModule{
- module: module,
- bootDexJar: nilPathHandler(h.bootDexJar(), "bootDexJar", module),
- flagsCSV: nilPathHandler(h.flagsCSV(), "flagsCSV", module),
- indexCSV: nilPathHandler(h.indexCSV(), "indexCSV", module),
- metadataCSV: nilPathHandler(h.metadataCSV(), "metadataCSV", module),
- }
-
- // If any errors were reported when trying to populate the hiddenAPISupportingModule struct
- // then don't add it to the list.
- if ctx.Failed() {
- continue
- }
-
- hiddenAPISupportingModules = append(hiddenAPISupportingModules, hiddenAPISupportingModule)
- } else if _, ok := module.(*DexImport); ok {
- // Ignore this for the purposes of hidden API processing
- } else {
- ctx.ModuleErrorf("module %s of type %s does not support hidden API processing", module, ctx.OtherModuleType(module))
- }
- }
-
- moduleSpecificFlagsPaths := android.Paths{}
- for _, module := range hiddenAPISupportingModules {
- moduleSpecificFlagsPaths = append(moduleSpecificFlagsPaths, module.flagsCSV)
- }
-
flagFileInfo := b.properties.Hidden_api.hiddenAPIFlagFileInfo(ctx)
for _, fragment := range fragments {
if ctx.OtherModuleHasProvider(fragment, hiddenAPIFlagFileInfoProvider) {
@@ -362,61 +290,53 @@
// Store the information for testing.
ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo)
- outputPath := hiddenAPISingletonPaths(ctx).flags
- baseFlagsPath := hiddenAPISingletonPaths(ctx).stubFlags
- buildRuleToGenerateHiddenApiFlags(ctx, "hiddenAPIFlagsFile", "hiddenapi flags", outputPath, baseFlagsPath, moduleSpecificFlagsPaths, &flagFileInfo)
-
- b.generateHiddenAPIStubFlagsRules(ctx, hiddenAPISupportingModules)
- b.generateHiddenAPIIndexRules(ctx, hiddenAPISupportingModules)
- b.generatedHiddenAPIMetadataRules(ctx, hiddenAPISupportingModules)
-}
-
-func (b *platformBootclasspathModule) generateHiddenAPIStubFlagsRules(ctx android.ModuleContext, modules []hiddenAPISupportingModule) {
- bootDexJars := android.Paths{}
- for _, module := range modules {
- bootDexJars = append(bootDexJars, module.bootDexJar)
- }
+ hiddenAPIModules := gatherHiddenAPIModuleFromContents(ctx, modules)
sdkKindToStubPaths := hiddenAPIGatherStubLibDexJarPaths(ctx, nil)
- outputPath := hiddenAPISingletonPaths(ctx).stubFlags
- rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, outputPath, bootDexJars, sdkKindToStubPaths)
+ // Generate the monolithic stub-flags.csv file.
+ bootDexJars := extractBootDexJarsFromHiddenAPIModules(ctx, hiddenAPIModules)
+ stubFlags := hiddenAPISingletonPaths(ctx).stubFlags
+ rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlags, bootDexJars, sdkKindToStubPaths)
rule.Build("platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags")
+
+ // Extract the classes jars from the contents.
+ classesJars := extractClassJarsFromHiddenAPIModules(ctx, hiddenAPIModules)
+
+ // Generate the annotation-flags.csv file from all the module annotations.
+ annotationFlags := android.PathForModuleOut(ctx, "hiddenapi-monolithic", "annotation-flags.csv")
+ buildRuleToGenerateAnnotationFlags(ctx, "monolithic hiddenapi flags", classesJars, stubFlags, annotationFlags)
+
+ // Generate the monotlithic hiddenapi-flags.csv file.
+ allFlags := hiddenAPISingletonPaths(ctx).flags
+ buildRuleToGenerateHiddenApiFlags(ctx, "hiddenAPIFlagsFile", "hiddenapi flags", allFlags, stubFlags, annotationFlags, &flagFileInfo)
+
+ // Generate an intermediate monolithic hiddenapi-metadata.csv file directly from the annotations
+ // in the source code.
+ intermediateMetadataCSV := android.PathForModuleOut(ctx, "hiddenapi-monolithic", "intermediate-metadata.csv")
+ buildRuleToGenerateMetadata(ctx, "monolithic hidden API metadata", classesJars, stubFlags, intermediateMetadataCSV)
+
+ // Reformat the intermediate file to add | quotes just in case that is important for the tools
+ // that consume the metadata file.
+ // TODO(b/179354495): Investigate whether it is possible to remove this reformatting step.
+ metadataCSV := hiddenAPISingletonPaths(ctx).metadata
+ b.buildRuleMergeCSV(ctx, "reformat monolithic hidden API metadata", android.Paths{intermediateMetadataCSV}, metadataCSV)
+
+ // Generate the monolithic hiddenapi-index.csv file directly from the CSV files in the classes
+ // jars.
+ indexCSV := hiddenAPISingletonPaths(ctx).index
+ buildRuleToGenerateIndex(ctx, "monolithic hidden API index", classesJars, indexCSV)
}
-func (b *platformBootclasspathModule) generateHiddenAPIIndexRules(ctx android.ModuleContext, modules []hiddenAPISupportingModule) {
- indexes := android.Paths{}
- for _, module := range modules {
- indexes = append(indexes, module.indexCSV)
- }
-
+func (b *platformBootclasspathModule) buildRuleMergeCSV(ctx android.ModuleContext, desc string, inputPaths android.Paths, outputPath android.WritablePath) {
rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().
BuiltTool("merge_csv").
Flag("--key_field signature").
- FlagWithArg("--header=", "signature,file,startline,startcol,endline,endcol,properties").
- FlagWithOutput("--output=", hiddenAPISingletonPaths(ctx).index).
- Inputs(indexes)
- rule.Build("platform-bootclasspath-monolithic-hiddenapi-index", "monolithic hidden API index")
-}
-
-func (b *platformBootclasspathModule) generatedHiddenAPIMetadataRules(ctx android.ModuleContext, modules []hiddenAPISupportingModule) {
- metadataCSVFiles := android.Paths{}
- for _, module := range modules {
- metadataCSVFiles = append(metadataCSVFiles, module.metadataCSV)
- }
-
- rule := android.NewRuleBuilder(pctx, ctx)
-
- outputPath := hiddenAPISingletonPaths(ctx).metadata
-
- rule.Command().
- BuiltTool("merge_csv").
- Flag("--key_field signature").
FlagWithOutput("--output=", outputPath).
- Inputs(metadataCSVFiles)
+ Inputs(inputPaths)
- rule.Build("platform-bootclasspath-monolithic-hiddenapi-metadata", "monolithic hidden API metadata")
+ rule.Build(desc, desc)
}
// generateHiddenApiMakeVars generates make variables needed by hidden API related make rules, e.g.
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
index cf2eab3..efcbc80 100644
--- a/java/platform_bootclasspath_test.go
+++ b/java/platform_bootclasspath_test.go
@@ -427,20 +427,14 @@
}
`)
- platformBootclasspath := result.ModuleForTests("myplatform-bootclasspath", "android_common")
- indexRule := platformBootclasspath.Rule("platform-bootclasspath-monolithic-hiddenapi-index")
- CheckHiddenAPIRuleInputs(t, `
-.intermediates/bar/android_common/hiddenapi/index.csv
-.intermediates/foo/android_common/hiddenapi/index.csv
-`,
- indexRule)
-
// Make sure that the foo-hiddenapi-annotations.jar is included in the inputs to the rules that
// creates the index.csv file.
- foo := result.ModuleForTests("foo", "android_common")
- indexParams := foo.Output("hiddenapi/index.csv")
+ platformBootclasspath := result.ModuleForTests("myplatform-bootclasspath", "android_common")
+ indexRule := platformBootclasspath.Rule("monolithic_hidden_API_index")
CheckHiddenAPIRuleInputs(t, `
+.intermediates/bar/android_common/javac/bar.jar
.intermediates/foo-hiddenapi-annotations/android_common/javac/foo-hiddenapi-annotations.jar
.intermediates/foo/android_common/javac/foo.jar
-`, indexParams)
+`,
+ indexRule)
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 6153615..f04f837 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -2128,7 +2128,7 @@
if dexOutputPath := di.PrebuiltExportPath(module.BaseModuleName(), ".dexjar"); dexOutputPath != nil {
module.dexJarFile = dexOutputPath
module.initHiddenAPI(ctx, module.configurationName)
- module.hiddenAPIExtractInformation(ctx, dexOutputPath, module.findScopePaths(apiScopePublic).stubsImplPath[0])
+ module.hiddenAPIUpdatePaths(ctx, dexOutputPath, module.findScopePaths(apiScopePublic).stubsImplPath[0])
} else {
// This should never happen as a variant for a prebuilt_apex is only created if the
// prebuilt_apex has been configured to export the java library dex file.