summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/classpath_fragment.go96
-rw-r--r--java/dexpreopt_bootjars.go2
-rw-r--r--java/dexpreopt_bootjars_test.go3
-rw-r--r--java/dexpreopt_config.go2
-rw-r--r--java/hiddenapi.go7
-rw-r--r--java/hiddenapi_modular.go181
-rw-r--r--java/hiddenapi_singleton.go106
-rw-r--r--java/hiddenapi_singleton_test.go55
-rw-r--r--java/java_test.go8
-rw-r--r--java/lint.go42
-rw-r--r--java/platform_bootclasspath.go96
-rw-r--r--java/platform_bootclasspath_test.go142
12 files changed, 481 insertions, 259 deletions
diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go
index adbe490f3..d4974600f 100644
--- a/java/classpath_fragment.go
+++ b/java/classpath_fragment.go
@@ -17,6 +17,9 @@
package java
import (
+ "fmt"
+ "strings"
+
"android/soong/android"
)
@@ -47,21 +50,102 @@ type classpathFragmentProperties struct {
type classpathFragment interface {
android.Module
- classpathFragmentBase() *classpathFragmentBase
+ classpathFragmentBase() *ClasspathFragmentBase
}
-// classpathFragmentBase is meant to be embedded in any module types that implement classpathFragment;
+// ClasspathFragmentBase is meant to be embedded in any module types that implement classpathFragment;
// such modules are expected to call initClasspathFragment().
-type classpathFragmentBase struct {
+type ClasspathFragmentBase struct {
properties classpathFragmentProperties
- classpathType classpathType
-
outputFilepath android.OutputPath
+ installDirPath android.InstallPath
}
-// Initializes classpathFragmentBase struct. Must be called by all modules that include classpathFragmentBase.
+func (c *ClasspathFragmentBase) classpathFragmentBase() *ClasspathFragmentBase {
+ return c
+}
+
+// Initializes ClasspathFragmentBase struct. Must be called by all modules that include ClasspathFragmentBase.
func initClasspathFragment(c classpathFragment) {
base := c.classpathFragmentBase()
c.AddProperties(&base.properties)
}
+
+// Matches definition of Jar in packages/modules/SdkExtensions/proto/classpaths.proto
+type classpathJar struct {
+ path string
+ classpath classpathType
+ // TODO(satayev): propagate min/max sdk versions for the jars
+ minSdkVersion int32
+ maxSdkVersion int32
+}
+
+func (c *ClasspathFragmentBase) generateAndroidBuildActions(ctx android.ModuleContext) {
+ outputFilename := ctx.ModuleName() + ".pb"
+ c.outputFilepath = android.PathForModuleOut(ctx, outputFilename).OutputPath
+ c.installDirPath = android.PathForModuleInstall(ctx, "etc", "classpaths")
+
+ var jars []classpathJar
+ jars = appendClasspathJar(jars, BOOTCLASSPATH, defaultBootclasspath(ctx)...)
+ jars = appendClasspathJar(jars, DEX2OATBOOTCLASSPATH, defaultBootImageConfig(ctx).getAnyAndroidVariant().dexLocationsDeps...)
+ jars = appendClasspathJar(jars, SYSTEMSERVERCLASSPATH, systemServerClasspath(ctx)...)
+
+ generatedJson := android.PathForModuleOut(ctx, outputFilename+".json")
+ writeClasspathsJson(ctx, generatedJson, jars)
+
+ rule := android.NewRuleBuilder(pctx, ctx)
+ rule.Command().
+ BuiltTool("conv_classpaths_proto").
+ Flag("encode").
+ Flag("--format=json").
+ FlagWithInput("--input=", generatedJson).
+ FlagWithOutput("--output=", c.outputFilepath)
+
+ rule.Build("classpath_fragment", "Compiling "+c.outputFilepath.String())
+}
+
+func writeClasspathsJson(ctx android.ModuleContext, output android.WritablePath, jars []classpathJar) {
+ var content strings.Builder
+ fmt.Fprintf(&content, "{\n")
+ fmt.Fprintf(&content, "\"jars\": [\n")
+ for idx, jar := range jars {
+ fmt.Fprintf(&content, "{\n")
+
+ fmt.Fprintf(&content, "\"relativePath\": \"%s\",\n", jar.path)
+ fmt.Fprintf(&content, "\"classpath\": \"%s\"\n", jar.classpath)
+
+ if idx < len(jars)-1 {
+ fmt.Fprintf(&content, "},\n")
+ } else {
+ fmt.Fprintf(&content, "}\n")
+ }
+ }
+ fmt.Fprintf(&content, "]\n")
+ fmt.Fprintf(&content, "}\n")
+ android.WriteFileRule(ctx, output, content.String())
+}
+
+func appendClasspathJar(slice []classpathJar, classpathType classpathType, paths ...string) (result []classpathJar) {
+ result = append(result, slice...)
+ for _, path := range paths {
+ result = append(result, classpathJar{
+ path: path,
+ classpath: classpathType,
+ })
+ }
+ return
+}
+
+func (c *ClasspathFragmentBase) getAndroidMkEntries() []android.AndroidMkEntries {
+ return []android.AndroidMkEntries{android.AndroidMkEntries{
+ Class: "ETC",
+ OutputFile: android.OptionalPathForPath(c.outputFilepath),
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.SetString("LOCAL_MODULE_PATH", c.installDirPath.ToMakePath().String())
+ entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.outputFilepath.Base())
+ },
+ },
+ }}
+}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 7137f33ba..e57c3e98d 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -484,7 +484,7 @@ func getBootJar(ctx android.SingletonContext, bootjars android.ConfiguredJarList
// Now match the apex part of the boot image configuration.
requiredApex := bootjars.Apex(index)
- if requiredApex == "platform" {
+ if requiredApex == "platform" || requiredApex == "system_ext" {
if len(apexInfo.InApexes) != 0 {
// A platform variant is required but this is for an apex so ignore it.
return -1, nil, nil
diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go
index d78651d90..73f21d12e 100644
--- a/java/dexpreopt_bootjars_test.go
+++ b/java/dexpreopt_bootjars_test.go
@@ -35,6 +35,7 @@ func testDexpreoptBoot(t *testing.T, ruleFile string, expectedInputs, expectedOu
name: "bar",
srcs: ["b.java"],
installable: true,
+ system_ext_specific: true,
}
dex_import {
@@ -47,7 +48,7 @@ func testDexpreoptBoot(t *testing.T, ruleFile string, expectedInputs, expectedOu
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("foo"),
- dexpreopt.FixtureSetBootJars("platform:foo", "platform:bar", "platform:baz"),
+ dexpreopt.FixtureSetBootJars("platform:foo", "system_ext:bar", "platform:baz"),
).RunTestWithBp(t, bp)
dexpreoptBootJars := result.SingletonForTests("dex_bootjars")
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 64b265640..656f5ef71 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -26,7 +26,7 @@ import (
// systemServerClasspath returns the on-device locations of the modules in the system server classpath. It is computed
// once the first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same
// ctx.Config().
-func systemServerClasspath(ctx android.MakeVarsContext) []string {
+func systemServerClasspath(ctx android.PathContext) []string {
return ctx.Config().OnceStringSlice(systemServerClasspathKey, func() []string {
global := dexpreopt.GetGlobalConfig(ctx)
var systemServerClasspathLocations []string
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index 208ced769..3ecb9772a 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -111,6 +111,13 @@ type hiddenAPIIntf interface {
var _ hiddenAPIIntf = (*hiddenAPI)(nil)
+// hiddenAPISupportingModule is the interface that is implemented by any module that supports
+// contributing to the hidden API processing.
+type hiddenAPISupportingModule interface {
+ android.Module
+ hiddenAPIIntf
+}
+
// Initialize the hiddenapi structure
func (h *hiddenAPI) initHiddenAPI(ctx android.BaseModuleContext, configurationName string) {
// If hiddenapi processing is disabled treat this as inactive.
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index bed11fe39..7cf082b6a 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -20,9 +20,9 @@ import (
// Contains support for processing hiddenAPI in a modular fashion.
-// HiddenAPIAugmentationProperties contains paths to the files that can be used to augment the information
-// obtained from annotations within the source code in order to create the complete set of flags
-// that should be applied to the dex implementation jars on the bootclasspath.
+// HiddenAPIFlagFileProperties contains paths to the flag files that can be used to augment the
+// information obtained from annotations within the source code in order to create the complete set
+// of flags that should be applied to the dex implementation jars on the bootclasspath.
//
// Each property contains a list of paths. With the exception of the Unsupported_packages the paths
// of each property reference a plain text file that contains a java signature per line. The flags
@@ -31,7 +31,7 @@ import (
// The Unsupported_packages property contains a list of paths, each of which is a plain text file
// with one Java package per line. All members of all classes within that package (but not nested
// packages) will be updated in a property specific way.
-type HiddenAPIAugmentationProperties struct {
+type HiddenAPIFlagFileProperties struct {
// Marks each signature in the referenced files as being unsupported.
Unsupported []string `android:"path"`
@@ -60,45 +60,116 @@ type HiddenAPIAugmentationProperties struct {
Unsupported_packages []string `android:"path"`
}
-func (p *HiddenAPIAugmentationProperties) hiddenAPIAugmentationInfo(ctx android.ModuleContext) hiddenAPIAugmentationInfo {
- paths := func(paths []string) android.Paths { return android.PathsForModuleSrc(ctx, paths) }
- return hiddenAPIAugmentationInfo{
- Unsupported: paths(p.Unsupported),
- Removed: paths(p.Removed),
- Max_target_r_low_priority: paths(p.Max_target_r_low_priority),
- Max_target_q: paths(p.Max_target_q),
- Max_target_p: paths(p.Max_target_p),
- Max_target_o_low_priority: paths(p.Max_target_o_low_priority),
- Blocked: paths(p.Blocked),
- Unsupported_packages: paths(p.Unsupported_packages),
+func (p *HiddenAPIFlagFileProperties) hiddenAPIFlagFileInfo(ctx android.ModuleContext) hiddenAPIFlagFileInfo {
+ info := hiddenAPIFlagFileInfo{categoryToPaths: map[*hiddenAPIFlagFileCategory]android.Paths{}}
+ for _, category := range hiddenAPIFlagFileCategories {
+ paths := android.PathsForModuleSrc(ctx, category.propertyAccessor(p))
+ info.categoryToPaths[category] = paths
}
+ return info
}
-// hiddenAPIAugmentationInfo contains paths resolved from HiddenAPIAugmentationProperties
-type hiddenAPIAugmentationInfo struct {
- // See HiddenAPIAugmentationProperties.Unsupported
- Unsupported android.Paths
+type hiddenAPIFlagFileCategory struct {
+ // propertyName is the name of the property for this category.
+ propertyName string
- // See HiddenAPIAugmentationProperties.Removed
- Removed android.Paths
+ // propertyAccessor retrieves the value of the property for this category from the set of
+ // properties.
+ propertyAccessor func(properties *HiddenAPIFlagFileProperties) []string
- // See HiddenAPIAugmentationProperties.Max_target_r_low_priority
- Max_target_r_low_priority android.Paths
-
- // See HiddenAPIAugmentationProperties.Max_target_q
- Max_target_q android.Paths
-
- // See HiddenAPIAugmentationProperties.Max_target_p
- Max_target_p android.Paths
-
- // See HiddenAPIAugmentationProperties.Max_target_o_low_priority
- Max_target_o_low_priority android.Paths
+ // commandMutator adds the appropriate command line options for this category to the supplied
+ // command
+ commandMutator func(command *android.RuleBuilderCommand, path android.Path)
+}
- // See HiddenAPIAugmentationProperties.Blocked
- Blocked android.Paths
+var hiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{
+ // See HiddenAPIFlagFileProperties.Unsupported
+ {
+ propertyName: "unsupported",
+ propertyAccessor: func(properties *HiddenAPIFlagFileProperties) []string {
+ return properties.Unsupported
+ },
+ commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
+ command.FlagWithInput("--unsupported ", path)
+ },
+ },
+ // See HiddenAPIFlagFileProperties.Removed
+ {
+ propertyName: "removed",
+ propertyAccessor: func(properties *HiddenAPIFlagFileProperties) []string {
+ return properties.Removed
+ },
+ commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
+ command.FlagWithInput("--unsupported ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "removed")
+ },
+ },
+ // See HiddenAPIFlagFileProperties.Max_target_r_low_priority
+ {
+ propertyName: "max_target_r_low_priority",
+ propertyAccessor: func(properties *HiddenAPIFlagFileProperties) []string {
+ return properties.Max_target_r_low_priority
+ },
+ commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
+ command.FlagWithInput("--max-target-r ", path).FlagWithArg("--tag ", "lo-prio")
+ },
+ },
+ // See HiddenAPIFlagFileProperties.Max_target_q
+ {
+ propertyName: "max_target_q",
+ propertyAccessor: func(properties *HiddenAPIFlagFileProperties) []string {
+ return properties.Max_target_q
+ },
+ commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
+ command.FlagWithInput("--max-target-q ", path)
+ },
+ },
+ // See HiddenAPIFlagFileProperties.Max_target_p
+ {
+ propertyName: "max_target_p",
+ propertyAccessor: func(properties *HiddenAPIFlagFileProperties) []string {
+ return properties.Max_target_p
+ },
+ commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
+ command.FlagWithInput("--max-target-p ", path)
+ },
+ },
+ // See HiddenAPIFlagFileProperties.Max_target_o_low_priority
+ {
+ propertyName: "max_target_o_low_priority",
+ propertyAccessor: func(properties *HiddenAPIFlagFileProperties) []string {
+ return properties.Max_target_o_low_priority
+ },
+ commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
+ command.FlagWithInput("--max-target-o ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "lo-prio")
+ },
+ },
+ // See HiddenAPIFlagFileProperties.Blocked
+ {
+ propertyName: "blocked",
+ propertyAccessor: func(properties *HiddenAPIFlagFileProperties) []string {
+ return properties.Blocked
+ },
+ commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
+ command.FlagWithInput("--blocked ", path)
+ },
+ },
+ // See HiddenAPIFlagFileProperties.Unsupported_packages
+ {
+ propertyName: "unsupported_packages",
+ propertyAccessor: func(properties *HiddenAPIFlagFileProperties) []string {
+ return properties.Unsupported_packages
+ },
+ commandMutator: func(command *android.RuleBuilderCommand, path android.Path) {
+ command.FlagWithInput("--unsupported ", path).Flag("--packages ")
+ },
+ },
+}
- // See HiddenAPIAugmentationProperties.Unsupported_packages
- Unsupported_packages android.Paths
+// hiddenAPIFlagFileInfo contains paths resolved from HiddenAPIFlagFileProperties
+type hiddenAPIFlagFileInfo struct {
+ // categoryToPaths maps from the flag file category to the paths containing information for that
+ // category.
+ categoryToPaths map[*hiddenAPIFlagFileCategory]android.Paths
}
// ruleToGenerateHiddenApiFlags creates a rule to create the monolithic hidden API flags from the
@@ -125,7 +196,7 @@ type hiddenAPIAugmentationInfo struct {
//
// augmentationInfo is a struct containing paths to files that augment the information provided by
// the moduleSpecificFlagsPaths.
-func ruleToGenerateHiddenApiFlags(ctx android.BuilderContext, outputPath android.WritablePath, baseFlagsPath android.Path, moduleSpecificFlagsPaths android.Paths, augmentationInfo hiddenAPIAugmentationInfo) {
+func ruleToGenerateHiddenApiFlags(ctx android.BuilderContext, outputPath android.WritablePath, baseFlagsPath android.Path, moduleSpecificFlagsPaths android.Paths, augmentationInfo hiddenAPIFlagFileInfo) {
tempPath := android.PathForOutput(ctx, outputPath.Rel()+".tmp")
rule := android.NewRuleBuilder(pctx, ctx)
command := rule.Command().
@@ -134,36 +205,12 @@ func ruleToGenerateHiddenApiFlags(ctx android.BuilderContext, outputPath android
Inputs(moduleSpecificFlagsPaths).
FlagWithOutput("--output ", tempPath)
- for _, path := range augmentationInfo.Unsupported {
- command.FlagWithInput("--unsupported ", path)
- }
-
- for _, path := range augmentationInfo.Removed {
- command.FlagWithInput("--unsupported ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "removed")
- }
-
- for _, path := range augmentationInfo.Max_target_r_low_priority {
- command.FlagWithInput("--max-target-r ", path).FlagWithArg("--tag ", "lo-prio")
- }
-
- for _, path := range augmentationInfo.Max_target_q {
- command.FlagWithInput("--max-target-q ", path)
- }
-
- for _, path := range augmentationInfo.Max_target_p {
- command.FlagWithInput("--max-target-p ", path)
- }
-
- for _, path := range augmentationInfo.Max_target_o_low_priority {
- command.FlagWithInput("--max-target-o ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "lo-prio")
- }
-
- for _, path := range augmentationInfo.Blocked {
- command.FlagWithInput("--blocked ", path)
- }
-
- for _, path := range augmentationInfo.Unsupported_packages {
- command.FlagWithInput("--unsupported ", path).Flag("--packages ")
+ // Add the options for the different categories of flag files.
+ for _, category := range hiddenAPIFlagFileCategories {
+ paths := augmentationInfo.categoryToPaths[category]
+ for _, path := range paths {
+ category.commandMutator(command, path)
+ }
}
commitChangeForRestat(rule, tempPath, outputPath)
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 6ba5f35bc..ed0b72250 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -24,7 +24,6 @@ func init() {
func RegisterHiddenApiSingletonComponents(ctx android.RegistrationContext) {
ctx.RegisterSingletonType("hiddenapi", hiddenAPISingletonFactory)
- ctx.RegisterSingletonType("hiddenapi_index", hiddenAPIIndexSingletonFactory)
}
var PrepareForTestWithHiddenApiBuildComponents = android.FixtureRegisterWithContext(RegisterHiddenApiSingletonComponents)
@@ -116,7 +115,7 @@ func hiddenAPISingletonFactory() android.Singleton {
}
type hiddenAPISingleton struct {
- flags, metadata android.Path
+ flags android.Path
}
// hiddenAPI singleton rules
@@ -138,30 +137,25 @@ func (h *hiddenAPISingleton) GenerateBuildActions(ctx android.SingletonContext)
if ctx.Config().PrebuiltHiddenApiDir(ctx) != "" {
h.flags = 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)
- h.metadata = metadataRule(ctx)
} else {
h.flags = emptyFlagsRule(ctx)
}
}
// Export paths to Make. INTERNAL_PLATFORM_HIDDENAPI_FLAGS is used by Make rules in art/ and cts/.
-// Both paths are used to call dist-for-goals.
func (h *hiddenAPISingleton) MakeVars(ctx android.MakeVarsContext) {
if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
return
}
ctx.Strict("INTERNAL_PLATFORM_HIDDENAPI_FLAGS", h.flags.String())
-
- if h.metadata != nil {
- ctx.Strict("INTERNAL_PLATFORM_HIDDENAPI_GREYLIST_METADATA", h.metadata.String())
- }
}
// stubFlagsRule creates the rule to build hiddenapi-stub-flags.txt out of dex jars from stub modules and boot image
@@ -321,6 +315,17 @@ func prebuiltFlagsRule(ctx android.SingletonContext) android.Path {
return outputPath
}
+func prebuiltIndexRule(ctx android.SingletonContext) {
+ outputPath := hiddenAPISingletonPaths(ctx).index
+ inputPath := android.PathForSource(ctx, ctx.Config().PrebuiltHiddenApiDir(ctx), "hiddenapi-index.csv")
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Output: outputPath,
+ Input: inputPath,
+ })
+}
+
// 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 {
@@ -343,34 +348,6 @@ func emptyFlagsRule(ctx android.SingletonContext) android.Path {
return outputPath
}
-// metadataRule creates a rule to build hiddenapi-unsupported.csv out of the metadata.csv files generated for boot image
-// modules.
-func metadataRule(ctx android.SingletonContext) android.Path {
- var metadataCSV android.Paths
-
- ctx.VisitAllModules(func(module android.Module) {
- if h, ok := module.(hiddenAPIIntf); ok {
- if csv := h.metadataCSV(); csv != nil {
- metadataCSV = append(metadataCSV, csv)
- }
- }
- })
-
- rule := android.NewRuleBuilder(pctx, ctx)
-
- outputPath := hiddenAPISingletonPaths(ctx).metadata
-
- rule.Command().
- BuiltTool("merge_csv").
- Flag("--key_field signature").
- FlagWithOutput("--output=", outputPath).
- Inputs(metadataCSV)
-
- rule.Build("hiddenAPIGreylistMetadataFile", "hiddenapi greylist metadata")
-
- return outputPath
-}
-
// commitChangeForRestat adds a command to a rule that updates outputPath from tempPath if they are different. It
// also marks the rule as restat and marks the tempPath as a temporary file that should not be considered an output of
// the rule.
@@ -388,60 +365,3 @@ func commitChangeForRestat(rule *android.RuleBuilder, tempPath, outputPath andro
Text("fi").
Text(")")
}
-
-func hiddenAPIIndexSingletonFactory() android.Singleton {
- return &hiddenAPIIndexSingleton{}
-}
-
-type hiddenAPIIndexSingleton struct {
- index android.Path
-}
-
-func (h *hiddenAPIIndexSingleton) GenerateBuildActions(ctx android.SingletonContext) {
- // Don't run any hiddenapi rules if UNSAFE_DISABLE_HIDDENAPI_FLAGS=true
- if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
- return
- }
-
- if ctx.Config().PrebuiltHiddenApiDir(ctx) != "" {
- outputPath := hiddenAPISingletonPaths(ctx).index
- inputPath := android.PathForSource(ctx, ctx.Config().PrebuiltHiddenApiDir(ctx), "hiddenapi-index.csv")
-
- ctx.Build(pctx, android.BuildParams{
- Rule: android.Cp,
- Output: outputPath,
- Input: inputPath,
- })
-
- h.index = outputPath
- return
- }
-
- indexes := android.Paths{}
- ctx.VisitAllModules(func(module android.Module) {
- if h, ok := module.(hiddenAPIIntf); ok {
- if h.indexCSV() != nil {
- indexes = append(indexes, h.indexCSV())
- }
- }
- })
-
- 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("singleton-merged-hiddenapi-index", "Singleton merged Hidden API index")
-
- h.index = hiddenAPISingletonPaths(ctx).index
-}
-
-func (h *hiddenAPIIndexSingleton) MakeVars(ctx android.MakeVarsContext) {
- if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
- return
- }
-
- ctx.Strict("INTERNAL_PLATFORM_HIDDENAPI_INDEX", h.index.String())
-}
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index e5e1c2547..5ea9a5bca 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -50,61 +50,6 @@ func TestHiddenAPISingleton(t *testing.T) {
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want)
}
-func TestHiddenAPIIndexSingleton(t *testing.T) {
- result := android.GroupFixturePreparers(
- hiddenApiFixtureFactory,
- PrepareForTestWithJavaSdkLibraryFiles,
- FixtureWithLastReleaseApis("bar"),
- FixtureConfigureBootJars("platform:foo", "platform:bar"),
- ).RunTestWithBp(t, `
- java_library {
- name: "foo",
- srcs: ["a.java"],
- compile_dex: true,
-
- hiddenapi_additional_annotations: [
- "foo-hiddenapi-annotations",
- ],
- }
-
- java_library {
- name: "foo-hiddenapi-annotations",
- srcs: ["a.java"],
- compile_dex: true,
- }
-
- java_import {
- name: "foo",
- jars: ["a.jar"],
- compile_dex: true,
- prefer: false,
- }
-
- java_sdk_library {
- name: "bar",
- srcs: ["a.java"],
- compile_dex: true,
- }
- `)
-
- hiddenAPIIndex := result.SingletonForTests("hiddenapi_index")
- indexRule := hiddenAPIIndex.Rule("singleton-merged-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")
- CheckHiddenAPIRuleInputs(t, `
-.intermediates/foo-hiddenapi-annotations/android_common/javac/foo-hiddenapi-annotations.jar
-.intermediates/foo/android_common/javac/foo.jar
-`, indexParams)
-}
-
func TestHiddenAPISingletonWithSourceAndPrebuiltPreferredButNoDex(t *testing.T) {
expectedErrorMessage :=
"hiddenapi has determined that the source module \"foo\" should be ignored as it has been" +
diff --git a/java/java_test.go b/java/java_test.go
index fdf757902..052345871 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1261,6 +1261,14 @@ func TestJavaLintUsesCorrectBpConfig(t *testing.T) {
if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline mybaseline.xml") {
t.Error("did not use the correct file for baseline")
}
+
+ if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check NewApi") {
+ t.Error("should check NewApi errors")
+ }
+
+ if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check SomeCheck") {
+ t.Error("should combine NewApi errors with SomeCheck errors")
+ }
}
func TestGeneratedSources(t *testing.T) {
diff --git a/java/lint.go b/java/lint.go
index 30843dc93..aa308e669 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -57,24 +57,25 @@ type LintProperties struct {
}
type linter struct {
- name string
- manifest android.Path
- mergedManifest android.Path
- srcs android.Paths
- srcJars android.Paths
- resources android.Paths
- classpath android.Paths
- classes android.Path
- extraLintCheckJars android.Paths
- test bool
- library bool
- minSdkVersion string
- targetSdkVersion string
- compileSdkVersion string
- javaLanguageLevel string
- kotlinLanguageLevel string
- outputs lintOutputs
- properties LintProperties
+ name string
+ manifest android.Path
+ mergedManifest android.Path
+ srcs android.Paths
+ srcJars android.Paths
+ resources android.Paths
+ classpath android.Paths
+ classes android.Path
+ extraLintCheckJars android.Paths
+ test bool
+ library bool
+ minSdkVersion string
+ targetSdkVersion string
+ compileSdkVersion string
+ javaLanguageLevel string
+ kotlinLanguageLevel string
+ outputs lintOutputs
+ properties LintProperties
+ extraMainlineLintErrors []string
reports android.Paths
@@ -246,6 +247,7 @@ func (l *linter) writeLintProjectXML(ctx android.ModuleContext, rule *android.Ru
cmd.FlagWithInput("@",
android.PathForSource(ctx, "build/soong/java/lint_defaults.txt"))
+ cmd.FlagForEachArg("--error_check ", l.extraMainlineLintErrors)
cmd.FlagForEachArg("--disable_check ", l.properties.Lint.Disabled_checks)
cmd.FlagForEachArg("--warning_check ", l.properties.Lint.Warning_checks)
cmd.FlagForEachArg("--error_check ", l.properties.Lint.Error_checks)
@@ -282,6 +284,10 @@ func (l *linter) lint(ctx android.ModuleContext) {
return
}
+ if l.minSdkVersion != l.compileSdkVersion {
+ l.extraMainlineLintErrors = append(l.extraMainlineLintErrors, "NewApi")
+ }
+
extraLintCheckModules := ctx.GetDirectDepsWithTag(extraLintCheckTag)
for _, extraLintCheckModule := range extraLintCheckModules {
if ctx.OtherModuleHasProvider(extraLintCheckModule, JavaInfoProvider) {
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index d70098080..cb8ad683b 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -59,6 +59,7 @@ var _ android.ExcludeFromVisibilityEnforcementTag = platformBootclasspathDepende
type platformBootclasspathModule struct {
android.ModuleBase
+ ClasspathFragmentBase
properties platformBootclasspathProperties
@@ -99,28 +100,29 @@ type platformBootclasspathProperties struct {
// platform_bootclasspath.
Fragments []ApexVariantReference
- Hidden_api HiddenAPIAugmentationProperties
+ Hidden_api HiddenAPIFlagFileProperties
}
func platformBootclasspathFactory() android.Module {
m := &platformBootclasspathModule{}
m.AddProperties(&m.properties)
+ // TODO(satayev): split systemserver and apex jars into separate configs.
+ initClasspathFragment(m)
android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
return m
}
var _ android.OutputFileProducer = (*platformBootclasspathModule)(nil)
-// A minimal AndroidMkEntries is needed in order to support the dists property.
-func (b *platformBootclasspathModule) AndroidMkEntries() []android.AndroidMkEntries {
- return []android.AndroidMkEntries{
- {
- Class: "FAKE",
- // Need at least one output file in order for this to take effect.
- OutputFile: android.OptionalPathForPath(b.hiddenAPIFlagsCSV),
- Include: "$(BUILD_PHONY_PACKAGE)",
- },
- }
+func (b *platformBootclasspathModule) AndroidMkEntries() (entries []android.AndroidMkEntries) {
+ entries = append(entries, android.AndroidMkEntries{
+ Class: "FAKE",
+ // Need at least one output file in order for this to take effect.
+ OutputFile: android.OptionalPathForPath(b.hiddenAPIFlagsCSV),
+ Include: "$(BUILD_PHONY_PACKAGE)",
+ })
+ entries = append(entries, b.classpathFragmentBase().getAndroidMkEntries()...)
+ return
}
// Make the hidden API files available from the platform-bootclasspath module.
@@ -245,6 +247,8 @@ func addDependenciesOntoBootImageModules(ctx android.BottomUpMutatorContext, mod
}
func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ b.classpathFragmentBase().generateAndroidBuildActions(ctx)
+
ctx.VisitDirectDepsIf(isActiveModule, func(module android.Module) {
tag := ctx.OtherModuleDependencyTag(module)
if tag == platformBootclasspathModuleDepTag {
@@ -303,20 +307,78 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.
return
}
- moduleSpecificFlagsPaths := android.Paths{}
+ hiddenAPISupportingModules := []hiddenAPISupportingModule{}
for _, module := range modules {
- if h, ok := module.(hiddenAPIIntf); ok {
- if csv := h.flagsCSV(); csv != nil {
- moduleSpecificFlagsPaths = append(moduleSpecificFlagsPaths, csv)
+ if h, ok := module.(hiddenAPISupportingModule); ok {
+ if h.bootDexJar() == nil {
+ ctx.ModuleErrorf("module %s does not provide a bootDexJar file", module)
+ }
+ if h.flagsCSV() == nil {
+ ctx.ModuleErrorf("module %s does not provide a flagsCSV file", module)
+ }
+ if h.indexCSV() == nil {
+ ctx.ModuleErrorf("module %s does not provide an indexCSV file", module)
+ }
+ if h.metadataCSV() == nil {
+ ctx.ModuleErrorf("module %s does not provide a metadataCSV file", module)
}
+
+ if ctx.Failed() {
+ continue
+ }
+
+ hiddenAPISupportingModules = append(hiddenAPISupportingModules, h)
} else {
- ctx.ModuleErrorf("module %s of type %s does not implement hiddenAPIIntf", module, ctx.OtherModuleType(module))
+ ctx.ModuleErrorf("module %s of type %s does not support hidden API processing", module, ctx.OtherModuleType(module))
}
}
- augmentationInfo := b.properties.Hidden_api.hiddenAPIAugmentationInfo(ctx)
+ moduleSpecificFlagsPaths := android.Paths{}
+ for _, module := range hiddenAPISupportingModules {
+ moduleSpecificFlagsPaths = append(moduleSpecificFlagsPaths, module.flagsCSV())
+ }
+
+ augmentationInfo := b.properties.Hidden_api.hiddenAPIFlagFileInfo(ctx)
outputPath := hiddenAPISingletonPaths(ctx).flags
baseFlagsPath := hiddenAPISingletonPaths(ctx).stubFlags
ruleToGenerateHiddenApiFlags(ctx, outputPath, baseFlagsPath, moduleSpecificFlagsPaths, augmentationInfo)
+
+ b.generateHiddenAPIIndexRules(ctx, hiddenAPISupportingModules)
+ b.generatedHiddenAPIMetadataRules(ctx, hiddenAPISupportingModules)
+}
+
+func (b *platformBootclasspathModule) generateHiddenAPIIndexRules(ctx android.ModuleContext, modules []hiddenAPISupportingModule) {
+ indexes := android.Paths{}
+ for _, module := range modules {
+ indexes = append(indexes, module.indexCSV())
+ }
+
+ 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)
+
+ rule.Build("platform-bootclasspath-monolithic-hiddenapi-metadata", "monolithic hidden API metadata")
}
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
index c740911f1..e51b0493a 100644
--- a/java/platform_bootclasspath_test.go
+++ b/java/platform_bootclasspath_test.go
@@ -132,6 +132,89 @@ func TestPlatformBootclasspath(t *testing.T) {
})
}
+func TestPlatformBootclasspathVariant(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForTestWithPlatformBootclasspath,
+ android.FixtureWithRootAndroidBp(`
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ }
+ `),
+ ).RunTest(t)
+
+ variants := result.ModuleVariantsForTests("platform-bootclasspath")
+ android.AssertIntEquals(t, "expect 1 variant", 1, len(variants))
+}
+
+func TestPlatformBootclasspath_ClasspathFragmentPaths(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForTestWithPlatformBootclasspath,
+ android.FixtureWithRootAndroidBp(`
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ }
+ `),
+ ).RunTest(t)
+
+ p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
+ android.AssertStringEquals(t, "output filepath", p.Name()+".pb", p.ClasspathFragmentBase.outputFilepath.Base())
+ android.AssertPathRelativeToTopEquals(t, "install filepath", "out/soong/target/product/test_device/system/etc/classpaths", p.ClasspathFragmentBase.installDirPath)
+}
+
+func TestPlatformBootclasspathModule_AndroidMkEntries(t *testing.T) {
+ preparer := android.GroupFixturePreparers(
+ prepareForTestWithPlatformBootclasspath,
+ android.FixtureWithRootAndroidBp(`
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ }
+ `),
+ )
+
+ t.Run("AndroidMkEntries", func(t *testing.T) {
+ result := preparer.RunTest(t)
+
+ p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
+
+ entries := android.AndroidMkEntriesForTest(t, result.TestContext, p)
+ android.AssertIntEquals(t, "AndroidMkEntries count", 2, len(entries))
+ })
+
+ t.Run("hiddenapi-flags-entry", func(t *testing.T) {
+ result := preparer.RunTest(t)
+
+ p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
+
+ entries := android.AndroidMkEntriesForTest(t, result.TestContext, p)
+ got := entries[0].OutputFile
+ android.AssertBoolEquals(t, "valid output path", true, got.Valid())
+ android.AssertSame(t, "output filepath", p.hiddenAPIFlagsCSV, got.Path())
+ })
+
+ t.Run("classpath-fragment-entry", func(t *testing.T) {
+ result := preparer.RunTest(t)
+
+ want := map[string][]string{
+ "LOCAL_MODULE": {"platform-bootclasspath"},
+ "LOCAL_MODULE_CLASS": {"ETC"},
+ "LOCAL_INSTALLED_MODULE_STEM": {"platform-bootclasspath.pb"},
+ // Output and Install paths are tested separately in TestPlatformBootclasspath_ClasspathFragmentPaths
+ }
+
+ p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
+
+ entries := android.AndroidMkEntriesForTest(t, result.TestContext, p)
+ got := entries[1]
+ for k, expectedValue := range want {
+ if value, ok := got.EntryMap[k]; ok {
+ android.AssertDeepEquals(t, k, expectedValue, value)
+ } else {
+ t.Errorf("No %s defined, saw %q", k, got.EntryMap)
+ }
+ }
+ })
+}
+
func TestPlatformBootclasspath_Dist(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
@@ -172,3 +255,62 @@ func TestPlatformBootclasspath_Dist(t *testing.T) {
android.AssertStringEquals(t, "platform dist goals phony", ".PHONY: droidcore\n", goals[0])
android.AssertStringEquals(t, "platform dist goals call", "$(call dist-for-goals,droidcore,out/soong/hiddenapi/hiddenapi-flags.csv:hiddenapi-flags.csv)\n", android.StringRelativeToTop(result.Config, goals[1]))
}
+
+func TestPlatformBootclasspath_HiddenAPIMonolithicFiles(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
+ PrepareForTestWithJavaSdkLibraryFiles,
+ FixtureWithLastReleaseApis("bar"),
+ FixtureConfigureBootJars("platform:foo", "platform:bar"),
+ ).RunTestWithBp(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ compile_dex: true,
+
+ hiddenapi_additional_annotations: [
+ "foo-hiddenapi-annotations",
+ ],
+ }
+
+ java_library {
+ name: "foo-hiddenapi-annotations",
+ srcs: ["a.java"],
+ compile_dex: true,
+ }
+
+ java_import {
+ name: "foo",
+ jars: ["a.jar"],
+ compile_dex: true,
+ prefer: false,
+ }
+
+ java_sdk_library {
+ name: "bar",
+ srcs: ["a.java"],
+ compile_dex: true,
+ }
+
+ platform_bootclasspath {
+ name: "myplatform-bootclasspath",
+ }
+ `)
+
+ 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")
+ CheckHiddenAPIRuleInputs(t, `
+.intermediates/foo-hiddenapi-annotations/android_common/javac/foo-hiddenapi-annotations.jar
+.intermediates/foo/android_common/javac/foo.jar
+`, indexParams)
+}