Support java_sdk_library as java_libs of apex
When a java_sdk_library module is added, both impl jar and permission xml files are packaged together. For example, when a java_sdk_library "foo" is listed, following two entries will be in an APEX package. /javalibs/foo.jar /etc/permissions/foo.xml Bug: 145474221 Test: m com.android.cronet deapexer list com.android.cronet.apex Change-Id: If5883c02255e9309f20810b1532d3fbe73bf4e95
This commit is contained in:
@@ -22,7 +22,6 @@ import (
|
|||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
"android/soong/cc"
|
"android/soong/cc"
|
||||||
"android/soong/java"
|
|
||||||
|
|
||||||
"github.com/google/blueprint/proptools"
|
"github.com/google/blueprint/proptools"
|
||||||
)
|
)
|
||||||
@@ -119,7 +118,7 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexName, moduleDir string)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if fi.class == javaSharedLib {
|
if fi.class == javaSharedLib {
|
||||||
javaModule := fi.module.(*java.Library)
|
javaModule := fi.module.(javaLibrary)
|
||||||
// soong_java_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .jar Therefore
|
// soong_java_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .jar Therefore
|
||||||
// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
|
// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
|
||||||
// we will have foo.jar.jar
|
// we will have foo.jar.jar
|
||||||
|
27
apex/apex.go
27
apex/apex.go
@@ -872,10 +872,16 @@ func apexFileForShBinary(ctx android.BaseModuleContext, sh *android.ShBinary) ap
|
|||||||
return af
|
return af
|
||||||
}
|
}
|
||||||
|
|
||||||
func apexFileForJavaLibrary(ctx android.BaseModuleContext, java *java.Library) apexFile {
|
// TODO(b/146586360): replace javaLibrary(in apex/apex.go) with java.Dependency
|
||||||
|
type javaLibrary interface {
|
||||||
|
android.Module
|
||||||
|
java.Dependency
|
||||||
|
}
|
||||||
|
|
||||||
|
func apexFileForJavaLibrary(ctx android.BaseModuleContext, lib javaLibrary) apexFile {
|
||||||
dirInApex := "javalib"
|
dirInApex := "javalib"
|
||||||
fileToCopy := java.DexJarFile()
|
fileToCopy := lib.DexJar()
|
||||||
return newApexFile(ctx, fileToCopy, java.Name(), dirInApex, javaSharedLib, java)
|
return newApexFile(ctx, fileToCopy, lib.Name(), dirInApex, javaSharedLib, lib)
|
||||||
}
|
}
|
||||||
|
|
||||||
func apexFileForPrebuiltJavaLibrary(ctx android.BaseModuleContext, java *java.Import) apexFile {
|
func apexFileForPrebuiltJavaLibrary(ctx android.BaseModuleContext, java *java.Import) apexFile {
|
||||||
@@ -1022,6 +1028,21 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
filesInfo = append(filesInfo, af)
|
filesInfo = append(filesInfo, af)
|
||||||
return true // track transitive dependencies
|
return true // track transitive dependencies
|
||||||
}
|
}
|
||||||
|
} else if sdkLib, ok := child.(*java.SdkLibrary); ok {
|
||||||
|
af := apexFileForJavaLibrary(ctx, sdkLib)
|
||||||
|
if !af.Ok() {
|
||||||
|
ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
filesInfo = append(filesInfo, af)
|
||||||
|
|
||||||
|
pf := sdkLib.PermissionFile()
|
||||||
|
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 if javaLib, ok := child.(*java.Import); ok {
|
} else if javaLib, ok := child.(*java.Import); ok {
|
||||||
af := apexFileForPrebuiltJavaLibrary(ctx, javaLib)
|
af := apexFileForPrebuiltJavaLibrary(ctx, javaLib)
|
||||||
if !af.Ok() {
|
if !af.Ok() {
|
||||||
|
@@ -306,6 +306,7 @@ func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*andr
|
|||||||
java.RegisterJavaBuildComponents(ctx)
|
java.RegisterJavaBuildComponents(ctx)
|
||||||
java.RegisterSystemModulesBuildComponents(ctx)
|
java.RegisterSystemModulesBuildComponents(ctx)
|
||||||
java.RegisterAppBuildComponents(ctx)
|
java.RegisterAppBuildComponents(ctx)
|
||||||
|
ctx.RegisterModuleType("java_sdk_library", java.SdkLibraryFactory)
|
||||||
|
|
||||||
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
|
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
|
||||||
ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
|
ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
|
||||||
@@ -3252,6 +3253,44 @@ func TestLegacyAndroid10Support(t *testing.T) {
|
|||||||
ensureContains(t, args["opt_flags"], "--manifest_json "+module.Output("apex_manifest.json").Output.String())
|
ensureContains(t, args["opt_flags"], "--manifest_json "+module.Output("apex_manifest.json").Output.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestJavaSDKLibrary(t *testing.T) {
|
||||||
|
ctx, _ := testApex(t, `
|
||||||
|
apex {
|
||||||
|
name: "myapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
java_libs: ["foo"],
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
java_sdk_library {
|
||||||
|
name: "foo",
|
||||||
|
srcs: ["a.java"],
|
||||||
|
api_packages: ["foo"],
|
||||||
|
}
|
||||||
|
`, withFiles(map[string][]byte{
|
||||||
|
"api/current.txt": nil,
|
||||||
|
"api/removed.txt": nil,
|
||||||
|
"api/system-current.txt": nil,
|
||||||
|
"api/system-removed.txt": nil,
|
||||||
|
"api/test-current.txt": nil,
|
||||||
|
"api/test-removed.txt": nil,
|
||||||
|
}))
|
||||||
|
|
||||||
|
// java_sdk_library installs both impl jar and permission XML
|
||||||
|
ensureExactContents(t, ctx, "myapex", []string{
|
||||||
|
"javalib/foo.jar",
|
||||||
|
"etc/permissions/foo.xml",
|
||||||
|
})
|
||||||
|
// Permission XML should point to the activated path of impl jar of java_sdk_library
|
||||||
|
genXMLCommand := ctx.ModuleForTests("foo", "android_common_myapex").Output("foo.xml").RuleParams.Command
|
||||||
|
ensureContains(t, genXMLCommand, `<library name="foo" file="/apex/myapex/javalib/foo.jar"`)
|
||||||
|
}
|
||||||
|
|
||||||
func TestRejectNonInstallableJavaLibrary(t *testing.T) {
|
func TestRejectNonInstallableJavaLibrary(t *testing.T) {
|
||||||
testApexError(t, `"myjar" is not configured to be compiled into dex`, `
|
testApexError(t, `"myjar" is not configured to be compiled into dex`, `
|
||||||
apex {
|
apex {
|
||||||
|
@@ -426,10 +426,6 @@ func (j *Module) OutputFiles(tag string) (android.Paths, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *Module) DexJarFile() android.Path {
|
|
||||||
return j.dexJarFile
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ android.OutputFileProducer = (*Module)(nil)
|
var _ android.OutputFileProducer = (*Module)(nil)
|
||||||
|
|
||||||
type Dependency interface {
|
type Dependency interface {
|
||||||
|
@@ -29,12 +29,31 @@ import (
|
|||||||
"github.com/google/blueprint/proptools"
|
"github.com/google/blueprint/proptools"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
const (
|
||||||
sdkStubsLibrarySuffix = ".stubs"
|
sdkStubsLibrarySuffix = ".stubs"
|
||||||
sdkSystemApiSuffix = ".system"
|
sdkSystemApiSuffix = ".system"
|
||||||
sdkTestApiSuffix = ".test"
|
sdkTestApiSuffix = ".test"
|
||||||
sdkDocsSuffix = ".docs"
|
sdkDocsSuffix = ".docs"
|
||||||
sdkXmlFileSuffix = ".xml"
|
sdkXmlFileSuffix = ".xml"
|
||||||
|
permissionTemplate = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2018 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<permissions>
|
||||||
|
<library name="%s" file="%s"/>
|
||||||
|
</permissions>
|
||||||
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
type stubsLibraryDependencyTag struct {
|
type stubsLibraryDependencyTag struct {
|
||||||
@@ -134,6 +153,8 @@ type SdkLibrary struct {
|
|||||||
publicApiFilePath android.Path
|
publicApiFilePath android.Path
|
||||||
systemApiFilePath android.Path
|
systemApiFilePath android.Path
|
||||||
testApiFilePath android.Path
|
testApiFilePath android.Path
|
||||||
|
|
||||||
|
permissionFile android.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Dependency = (*SdkLibrary)(nil)
|
var _ Dependency = (*SdkLibrary)(nil)
|
||||||
@@ -163,6 +184,10 @@ func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|||||||
func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
module.Library.GenerateAndroidBuildActions(ctx)
|
module.Library.GenerateAndroidBuildActions(ctx)
|
||||||
|
|
||||||
|
if module.ApexName() != "" {
|
||||||
|
module.buildPermissionFile(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
// Record the paths to the header jars of the library (stubs and impl).
|
// Record the paths to the header jars of the library (stubs and impl).
|
||||||
// When this java_sdk_library is dependened from others via "libs" property,
|
// When this java_sdk_library is dependened from others via "libs" property,
|
||||||
// the recorded paths will be returned depending on the link type of the caller.
|
// the recorded paths will be returned depending on the link type of the caller.
|
||||||
@@ -198,6 +223,21 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (module *SdkLibrary) buildPermissionFile(ctx android.ModuleContext) {
|
||||||
|
xmlContent := strings.ReplaceAll(fmt.Sprintf(permissionTemplate, module.BaseModuleName(), module.implPath()), "\n", "\\n")
|
||||||
|
permissionFile := android.PathForModuleOut(ctx, module.xmlFileName())
|
||||||
|
|
||||||
|
rule := android.NewRuleBuilder()
|
||||||
|
rule.Command().Text("echo -e ").Text(proptools.ShellEscape(xmlContent)).Text(">").Output(permissionFile)
|
||||||
|
rule.Build(pctx, ctx, "gen_permission_xml", "Generate permission")
|
||||||
|
|
||||||
|
module.permissionFile = permissionFile
|
||||||
|
}
|
||||||
|
|
||||||
|
func (module *SdkLibrary) PermissionFile() android.Path {
|
||||||
|
return module.permissionFile
|
||||||
|
}
|
||||||
|
|
||||||
func (module *SdkLibrary) AndroidMkEntries() []android.AndroidMkEntries {
|
func (module *SdkLibrary) AndroidMkEntries() []android.AndroidMkEntries {
|
||||||
entriesList := module.Library.AndroidMkEntries()
|
entriesList := module.Library.AndroidMkEntries()
|
||||||
entries := &entriesList[0]
|
entries := &entriesList[0]
|
||||||
@@ -290,6 +330,12 @@ func (module *SdkLibrary) implName() string {
|
|||||||
|
|
||||||
// File path to the runtime implementation library
|
// File path to the runtime implementation library
|
||||||
func (module *SdkLibrary) implPath() string {
|
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"
|
partition := "system"
|
||||||
if module.SocSpecific() {
|
if module.SocSpecific() {
|
||||||
partition = "vendor"
|
partition = "vendor"
|
||||||
@@ -532,31 +578,11 @@ func (module *SdkLibrary) createDocs(mctx android.LoadHookContext, apiScope apiS
|
|||||||
|
|
||||||
// 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) {
|
||||||
template := `
|
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2018 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<permissions>
|
|
||||||
<library name="%s" file="%s"/>
|
|
||||||
</permissions>
|
|
||||||
`
|
|
||||||
// genrule to generate the xml file content from the template above
|
// genrule to generate the xml file content from the template above
|
||||||
// TODO: preserve newlines in the generate xml file. Newlines are being squashed
|
// TODO: preserve newlines in the generate xml file. Newlines are being squashed
|
||||||
// in the ninja file. Do we need to have an external tool for this?
|
// in the ninja file. Do we need to have an external tool for this?
|
||||||
xmlContent := fmt.Sprintf(template, module.BaseModuleName(), module.implPath())
|
xmlContent := fmt.Sprintf(permissionTemplate, module.BaseModuleName(), module.implPath())
|
||||||
genruleProps := struct {
|
genruleProps := struct {
|
||||||
Name *string
|
Name *string
|
||||||
Cmd *string
|
Cmd *string
|
||||||
@@ -666,10 +692,12 @@ func javaSdkLibraries(config android.Config) *[]string {
|
|||||||
func (module *SdkLibrary) CreateInternalModules(mctx android.LoadHookContext) {
|
func (module *SdkLibrary) CreateInternalModules(mctx android.LoadHookContext) {
|
||||||
if len(module.Library.Module.properties.Srcs) == 0 {
|
if len(module.Library.Module.properties.Srcs) == 0 {
|
||||||
mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
|
mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(module.sdkLibraryProperties.Api_packages) == 0 {
|
if len(module.sdkLibraryProperties.Api_packages) == 0 {
|
||||||
mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
|
mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
missing_current_api := false
|
missing_current_api := false
|
||||||
@@ -745,6 +773,7 @@ func (module *SdkLibrary) InitSdkLibraryProperties() {
|
|||||||
func SdkLibraryFactory() android.Module {
|
func SdkLibraryFactory() android.Module {
|
||||||
module := &SdkLibrary{}
|
module := &SdkLibrary{}
|
||||||
module.InitSdkLibraryProperties()
|
module.InitSdkLibraryProperties()
|
||||||
|
android.InitApexModule(module)
|
||||||
InitJavaModule(module, android.HostAndDeviceSupported)
|
InitJavaModule(module, android.HostAndDeviceSupported)
|
||||||
android.AddLoadHook(module, func(ctx android.LoadHookContext) { module.CreateInternalModules(ctx) })
|
android.AddLoadHook(module, func(ctx android.LoadHookContext) { module.CreateInternalModules(ctx) })
|
||||||
return module
|
return module
|
||||||
|
Reference in New Issue
Block a user