Merge "Permissions XML file for java_sdk_library is mutated for APEX"

This commit is contained in:
Jiyong Park 2020-02-19 23:57:14 +00:00 committed by Gerrit Code Review
commit 2d6d5d8995
4 changed files with 144 additions and 101 deletions

View file

@ -2111,13 +2111,6 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
return false return false
} }
filesInfo = append(filesInfo, af) 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 return true // track transitive dependencies
} else { } else {
ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child)) 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) { } else if java.IsJniDepTag(depTag) {
return true 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() { } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
ctx.ModuleErrorf("unexpected tag %q for indirect dependency %q", depTag, depName) ctx.ModuleErrorf("unexpected tag %q for indirect dependency %q", depTag, depName)
} }

View file

@ -3531,9 +3531,8 @@ func TestJavaSDKLibrary(t *testing.T) {
"etc/permissions/foo.xml", "etc/permissions/foo.xml",
}) })
// Permission XML should point to the activated path of impl jar of java_sdk_library // 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) sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_myapex").Rule("java_sdk_xml")
xml := sdkLibrary.XmlPermissionsFileContent() ensureContains(t, sdkLibrary.RuleParams.Command, `<library name=\"foo\" file=\"/apex/myapex/javalib/foo.jar\"`)
ensureContains(t, xml, `<library name="foo" file="/apex/myapex/javalib/foo.jar"`)
} }
func TestCompatConfig(t *testing.T) { func TestCompatConfig(t *testing.T) {

View file

@ -1184,7 +1184,7 @@ func TestJavaSdkLibrary(t *testing.T) {
ctx.ModuleForTests("foo"+sdkStubsSourceSuffix, "android_common") ctx.ModuleForTests("foo"+sdkStubsSourceSuffix, "android_common")
ctx.ModuleForTests("foo"+sdkStubsSourceSuffix+sdkSystemApiSuffix, "android_common") ctx.ModuleForTests("foo"+sdkStubsSourceSuffix+sdkSystemApiSuffix, "android_common")
ctx.ModuleForTests("foo"+sdkStubsSourceSuffix+sdkTestApiSuffix, "android_common") ctx.ModuleForTests("foo"+sdkStubsSourceSuffix+sdkTestApiSuffix, "android_common")
ctx.ModuleForTests("foo"+sdkXmlFileSuffix, "android_arm64_armv8-a") ctx.ModuleForTests("foo"+sdkXmlFileSuffix, "android_common")
ctx.ModuleForTests("foo.api.public.28", "") ctx.ModuleForTests("foo.api.public.28", "")
ctx.ModuleForTests("foo.api.system.28", "") ctx.ModuleForTests("foo.api.system.28", "")
ctx.ModuleForTests("foo.api.test.28", "") ctx.ModuleForTests("foo.api.test.28", "")

View file

@ -16,7 +16,6 @@ package java
import ( import (
"android/soong/android" "android/soong/android"
"android/soong/genrule"
"fmt" "fmt"
"io" "io"
@ -36,23 +35,23 @@ const (
sdkTestApiSuffix = ".test" sdkTestApiSuffix = ".test"
sdkStubsSourceSuffix = ".stubs.source" sdkStubsSourceSuffix = ".stubs.source"
sdkXmlFileSuffix = ".xml" sdkXmlFileSuffix = ".xml"
permissionsTemplate = `<?xml version="1.0" encoding="utf-8"?>\n` + permissionsTemplate = `<?xml version=\"1.0\" encoding=\"utf-8\"?>\n` +
`<!-- Copyright (C) 2018 The Android Open Source Project\n` + `<!-- Copyright (C) 2018 The Android Open Source Project\n` +
`\n` + `\n` +
` Licensed under the Apache License, Version 2.0 (the "License");\n` + ` Licensed under the Apache License, Version 2.0 (the \"License\");\n` +
` you may not use this file except in compliance with the License.\n` + ` you may not use this file except in compliance with the License.\n` +
` You may obtain a copy of the License at\n` + ` You may obtain a copy of the License at\n` +
`\n` + `\n` +
` http://www.apache.org/licenses/LICENSE-2.0\n` + ` http://www.apache.org/licenses/LICENSE-2.0\n` +
`\n` + `\n` +
` Unless required by applicable law or agreed to in writing, software\n` + ` Unless required by applicable law or agreed to in writing, software\n` +
` distributed under the License is distributed on an "AS IS" BASIS,\n` + ` distributed under the License is distributed on an \"AS IS\" BASIS,\n` +
` WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n` + ` WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n` +
` See the License for the specific language governing permissions and\n` + ` See the License for the specific language governing permissions and\n` +
` limitations under the License.\n` + ` limitations under the License.\n` +
`-->\n` + `-->\n` +
`<permissions>\n` + `<permissions>\n` +
` <library name="%s" file="%s"/>\n` + ` <library name=\"%s\" file=\"%s\"/>\n` +
`</permissions>\n` `</permissions>\n`
) )
@ -250,8 +249,6 @@ type SdkLibrary struct {
sdkLibraryProperties sdkLibraryProperties sdkLibraryProperties sdkLibraryProperties
commonToSdkLibraryAndImport commonToSdkLibraryAndImport
permissionsFile android.Path
} }
var _ Dependency = (*SdkLibrary)(nil) var _ Dependency = (*SdkLibrary)(nil)
@ -267,6 +264,13 @@ func (module *SdkLibrary) getActiveApiScopes() apiScopes {
var xmlPermissionsFileTag = dependencyTag{name: "xml-permissions-file"} 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) { func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
for _, apiScope := range module.getActiveApiScopes() { for _, apiScope := range module.getActiveApiScopes() {
// Add dependencies to the stubs library // Add dependencies to the stubs library
@ -278,7 +282,7 @@ func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
if !proptools.Bool(module.sdkLibraryProperties.Api_only) { if !proptools.Bool(module.sdkLibraryProperties.Api_only) {
// Add dependency to the rule for generating the xml permissions file // 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) 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) 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() 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 // Module name of the XML file for the lib
func (module *SdkLibrary) xmlFileName() string { func (module *SdkLibrary) xmlFileName() string {
return module.BaseModuleName() + sdkXmlFileSuffix 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. // Get the sdk version for use when compiling the stubs library.
func (module *SdkLibrary) sdkVersionForStubsLibrary(mctx android.LoadHookContext, apiScope *apiScope) string { func (module *SdkLibrary) sdkVersionForStubsLibrary(mctx android.LoadHookContext, apiScope *apiScope) string {
sdkDep := decodeSdkDep(mctx, sdkContext(&module.Library)) sdkDep := decodeSdkDep(mctx, sdkContext(&module.Library))
@ -615,58 +581,31 @@ func (module *SdkLibrary) createStubsSources(mctx android.LoadHookContext, apiSc
mctx.CreateModule(DroidstubsFactory, &props) 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 // Creates the xml file that publicizes the runtime library
func (module *SdkLibrary) createXmlFile(mctx android.LoadHookContext) { func (module *SdkLibrary) createXmlFile(mctx android.LoadHookContext) {
props := struct {
xmlContent := module.XmlPermissionsFileContent()
genRuleName := module.genXmlPermissionsFileName()
// Create a genrule module to create the XML permissions file.
genRuleProps := struct {
Name *string Name *string
Cmd *string Lib_name *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
// <partition>/etc/permissions
etcProps := struct {
Name *string
Src *string
Sub_dir *string
Soc_specific *bool Soc_specific *bool
Device_specific *bool Device_specific *bool
Product_specific *bool Product_specific *bool
System_ext_specific *bool System_ext_specific *bool
}{} }{
etcProps.Name = proptools.StringPtr(module.xmlFileName()) Name: proptools.StringPtr(module.xmlFileName()),
etcProps.Src = proptools.StringPtr(":" + genRuleName) Lib_name: proptools.StringPtr(module.BaseModuleName()),
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)
} }
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 { 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. // This module is just a wrapper for the stubs.
return module.sdkJars(ctx, sdkVersion) 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())
},
},
}}
}