Merge "Support java_sdk_library as java_libs of apex" am: 120d73fe4f am: 1d39e165f7

Change-Id: I67664d3ea1db1d5729ac9a298dee638f0cef97e8
This commit is contained in:
Automerger Merge Worker
2019-12-20 05:32:54 +00:00
5 changed files with 115 additions and 31 deletions

View File

@@ -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

View File

@@ -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() {

View File

@@ -299,6 +299,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.PreDepsMutators(RegisterPreDepsMutators) ctx.PreDepsMutators(RegisterPreDepsMutators)
@@ -3231,6 +3232,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 {

View File

@@ -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 {

View File

@@ -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