diff --git a/apex/apex.go b/apex/apex.go index 54a335a5f..84043a5ff 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2111,13 +2111,6 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { return false } filesInfo = append(filesInfo, af) - - pf := sdkLib.XmlPermissionsFile() - if pf == nil { - ctx.PropertyErrorf("java_libs", "%q failed to generate permission XML", depName) - return false - } - filesInfo = append(filesInfo, newApexFile(ctx, pf, pf.Base(), "etc/permissions", etc, nil)) return true // track transitive dependencies } else { ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child)) @@ -2230,6 +2223,10 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } else if java.IsJniDepTag(depTag) { return true + } else if java.IsXmlPermissionsFileDepTag(depTag) { + if prebuilt, ok := child.(android.PrebuiltEtcModule); ok { + filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName)) + } } else if am.CanHaveApexVariants() && am.IsInstallableToApex() { ctx.ModuleErrorf("unexpected tag %q for indirect dependency %q", depTag, depName) } diff --git a/apex/apex_test.go b/apex/apex_test.go index 0420586de..c08a11ec0 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -3488,9 +3488,8 @@ func TestJavaSDKLibrary(t *testing.T) { "etc/permissions/foo.xml", }) // Permission XML should point to the activated path of impl jar of java_sdk_library - sdkLibrary := ctx.ModuleForTests("foo", "android_common_myapex").Module().(*java.SdkLibrary) - xml := sdkLibrary.XmlPermissionsFileContent() - ensureContains(t, xml, `\n` + + permissionsTemplate = `\n` + `\n` + `\n` + - ` \n` + + ` \n` + `\n` ) @@ -250,8 +249,6 @@ type SdkLibrary struct { sdkLibraryProperties sdkLibraryProperties commonToSdkLibraryAndImport - - permissionsFile android.Path } var _ Dependency = (*SdkLibrary)(nil) @@ -267,6 +264,13 @@ func (module *SdkLibrary) getActiveApiScopes() apiScopes { var xmlPermissionsFileTag = dependencyTag{name: "xml-permissions-file"} +func IsXmlPermissionsFileDepTag(depTag blueprint.DependencyTag) bool { + if dt, ok := depTag.(dependencyTag); ok { + return dt == xmlPermissionsFileTag + } + return false +} + func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { for _, apiScope := range module.getActiveApiScopes() { // Add dependencies to the stubs library @@ -278,7 +282,7 @@ func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { if !proptools.Bool(module.sdkLibraryProperties.Api_only) { // Add dependency to the rule for generating the xml permissions file - ctx.AddDependency(module, xmlPermissionsFileTag, module.genXmlPermissionsFileName()) + ctx.AddDependency(module, xmlPermissionsFileTag, module.xmlFileName()) } module.Library.deps(ctx) @@ -314,18 +318,6 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag) } } - if tag == xmlPermissionsFileTag { - if genRule, ok := to.(genrule.SourceFileGenerator); ok { - pf := genRule.GeneratedSourceFiles() - if len(pf) != 1 { - ctx.ModuleErrorf("%q failed to generate permission XML", otherName) - } else { - module.permissionsFile = pf[0] - } - } else { - ctx.ModuleErrorf("depends on module %q to generate xml permissions file but it does not provide any outputs", otherName) - } - } }) } @@ -389,37 +381,11 @@ func (module *SdkLibrary) implName() string { return module.BaseModuleName() } -// File path to the runtime implementation library -func (module *SdkLibrary) implPath() string { - if apexName := module.ApexName(); apexName != "" { - // TODO(b/146468504): ApexName() is only a soong module name, not apex name. - // In most cases, this works fine. But when apex_name is set or override_apex is used - // this can be wrong. - return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, module.implName()) - } - partition := "system" - if module.SocSpecific() { - partition = "vendor" - } else if module.DeviceSpecific() { - partition = "odm" - } else if module.ProductSpecific() { - partition = "product" - } else if module.SystemExtSpecific() { - partition = "system_ext" - } - return "/" + partition + "/framework/" + module.implName() + ".jar" -} - // Module name of the XML file for the lib func (module *SdkLibrary) xmlFileName() string { return module.BaseModuleName() + sdkXmlFileSuffix } -// Module name of the rule for generating the XML permissions file -func (module *SdkLibrary) genXmlPermissionsFileName() string { - return "gen-" + module.BaseModuleName() + sdkXmlFileSuffix -} - // Get the sdk version for use when compiling the stubs library. func (module *SdkLibrary) sdkVersionForStubsLibrary(mctx android.LoadHookContext, apiScope *apiScope) string { sdkDep := decodeSdkDep(mctx, sdkContext(&module.Library)) @@ -615,58 +581,31 @@ func (module *SdkLibrary) createStubsSources(mctx android.LoadHookContext, apiSc mctx.CreateModule(DroidstubsFactory, &props) } -func (module *SdkLibrary) XmlPermissionsFile() android.Path { - return module.permissionsFile -} - -func (module *SdkLibrary) XmlPermissionsFileContent() string { - return fmt.Sprintf(permissionsTemplate, module.BaseModuleName(), module.implPath()) -} - // Creates the xml file that publicizes the runtime library func (module *SdkLibrary) createXmlFile(mctx android.LoadHookContext) { - - xmlContent := module.XmlPermissionsFileContent() - - genRuleName := module.genXmlPermissionsFileName() - - // Create a genrule module to create the XML permissions file. - genRuleProps := struct { - Name *string - Cmd *string - Out []string - }{ - Name: proptools.StringPtr(genRuleName), - Cmd: proptools.StringPtr("echo -e '" + xmlContent + "' > '$(out)'"), - Out: []string{module.xmlFileName()}, - } - - mctx.CreateModule(genrule.GenRuleFactory, &genRuleProps) - - // creates a prebuilt_etc module to actually place the xml file under - // /etc/permissions - etcProps := struct { + props := struct { Name *string - Src *string - Sub_dir *string + Lib_name *string Soc_specific *bool Device_specific *bool Product_specific *bool System_ext_specific *bool - }{} - etcProps.Name = proptools.StringPtr(module.xmlFileName()) - etcProps.Src = proptools.StringPtr(":" + genRuleName) - etcProps.Sub_dir = proptools.StringPtr("permissions") - if module.SocSpecific() { - etcProps.Soc_specific = proptools.BoolPtr(true) - } else if module.DeviceSpecific() { - etcProps.Device_specific = proptools.BoolPtr(true) - } else if module.ProductSpecific() { - etcProps.Product_specific = proptools.BoolPtr(true) - } else if module.SystemExtSpecific() { - etcProps.System_ext_specific = proptools.BoolPtr(true) + }{ + Name: proptools.StringPtr(module.xmlFileName()), + Lib_name: proptools.StringPtr(module.BaseModuleName()), } - mctx.CreateModule(android.PrebuiltEtcFactory, &etcProps) + + if module.SocSpecific() { + props.Soc_specific = proptools.BoolPtr(true) + } else if module.DeviceSpecific() { + props.Device_specific = proptools.BoolPtr(true) + } else if module.ProductSpecific() { + props.Product_specific = proptools.BoolPtr(true) + } else if module.SystemExtSpecific() { + props.System_ext_specific = proptools.BoolPtr(true) + } + + mctx.CreateModule(sdkLibraryXmlFactory, &props) } func PrebuiltJars(ctx android.BaseModuleContext, baseName string, s sdkSpec) android.Paths { @@ -1039,3 +978,111 @@ func (module *sdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleCont // This module is just a wrapper for the stubs. return module.sdkJars(ctx, sdkVersion) } + +// +// java_sdk_library_xml +// +type sdkLibraryXml struct { + android.ModuleBase + android.DefaultableModuleBase + android.ApexModuleBase + + properties sdkLibraryXmlProperties + + outputFilePath android.OutputPath + installDirPath android.InstallPath +} + +type sdkLibraryXmlProperties struct { + // canonical name of the lib + Lib_name *string +} + +// java_sdk_library_xml builds the permission xml file for a java_sdk_library. +// Not to be used directly by users. java_sdk_library internally uses this. +func sdkLibraryXmlFactory() android.Module { + module := &sdkLibraryXml{} + + module.AddProperties(&module.properties) + + android.InitApexModule(module) + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) + + return module +} + +// from android.PrebuiltEtcModule +func (module *sdkLibraryXml) SubDir() string { + return "permissions" +} + +// from android.PrebuiltEtcModule +func (module *sdkLibraryXml) OutputFile() android.OutputPath { + return module.outputFilePath +} + +// from android.ApexModule +func (module *sdkLibraryXml) AvailableFor(what string) bool { + return true +} + +func (module *sdkLibraryXml) DepsMutator(ctx android.BottomUpMutatorContext) { + // do nothing +} + +// File path to the runtime implementation library +func (module *sdkLibraryXml) implPath() string { + implName := proptools.String(module.properties.Lib_name) + if apexName := module.ApexName(); apexName != "" { + // TODO(b/146468504): ApexName() is only a soong module name, not apex name. + // In most cases, this works fine. But when apex_name is set or override_apex is used + // this can be wrong. + return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, implName) + } + partition := "system" + if module.SocSpecific() { + partition = "vendor" + } else if module.DeviceSpecific() { + partition = "odm" + } else if module.ProductSpecific() { + partition = "product" + } else if module.SystemExtSpecific() { + partition = "system_ext" + } + return "/" + partition + "/framework/" + implName + ".jar" +} + +func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleContext) { + libName := proptools.String(module.properties.Lib_name) + xmlContent := fmt.Sprintf(permissionsTemplate, libName, module.implPath()) + + module.outputFilePath = android.PathForModuleOut(ctx, libName+".xml").OutputPath + rule := android.NewRuleBuilder() + rule.Command(). + Text("/bin/bash -c \"echo -e '" + xmlContent + "'\" > "). + Output(module.outputFilePath) + + rule.Build(pctx, ctx, "java_sdk_xml", "Permission XML") + + module.installDirPath = android.PathForModuleInstall(ctx, "etc", module.SubDir()) +} + +func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries { + if !module.IsForPlatform() { + return []android.AndroidMkEntries{android.AndroidMkEntries{ + Disabled: true, + }} + } + + return []android.AndroidMkEntries{android.AndroidMkEntries{ + Class: "ETC", + OutputFile: android.OptionalPathForPath(module.outputFilePath), + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(entries *android.AndroidMkEntries) { + entries.SetString("LOCAL_MODULE_TAGS", "optional") + entries.SetString("LOCAL_MODULE_PATH", module.installDirPath.ToMakePath().String()) + entries.SetString("LOCAL_INSTALLED_MODULE_STEM", module.outputFilePath.Base()) + }, + }, + }} +}