diff options
Diffstat (limited to 'java')
| -rw-r--r-- | java/classpath_fragment.go | 96 | ||||
| -rw-r--r-- | java/dexpreopt_bootjars.go | 2 | ||||
| -rw-r--r-- | java/dexpreopt_bootjars_test.go | 3 | ||||
| -rw-r--r-- | java/dexpreopt_config.go | 2 | ||||
| -rw-r--r-- | java/hiddenapi.go | 7 | ||||
| -rw-r--r-- | java/hiddenapi_modular.go | 181 | ||||
| -rw-r--r-- | java/hiddenapi_singleton.go | 106 | ||||
| -rw-r--r-- | java/hiddenapi_singleton_test.go | 55 | ||||
| -rw-r--r-- | java/java_test.go | 8 | ||||
| -rw-r--r-- | java/lint.go | 42 | ||||
| -rw-r--r-- | java/platform_bootclasspath.go | 96 | ||||
| -rw-r--r-- | java/platform_bootclasspath_test.go | 142 |
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) +} |