Implement InstallableModule for Java modules
This change enables the container information to be collected for Java modules. Test: m nothing --no-skip-soong-tests Bug: 338660802 Change-Id: I01bf99fa274275a608601ad6248d577ae8f6dffc
This commit is contained in:
@@ -37,6 +37,7 @@ bootstrap_go_package {
|
|||||||
"apex_test.go",
|
"apex_test.go",
|
||||||
"bootclasspath_fragment_test.go",
|
"bootclasspath_fragment_test.go",
|
||||||
"classpath_element_test.go",
|
"classpath_element_test.go",
|
||||||
|
"container_test.go",
|
||||||
"dexpreopt_bootjars_test.go",
|
"dexpreopt_bootjars_test.go",
|
||||||
"platform_bootclasspath_test.go",
|
"platform_bootclasspath_test.go",
|
||||||
"systemserver_classpath_fragment_test.go",
|
"systemserver_classpath_fragment_test.go",
|
||||||
|
329
apex/container_test.go
Normal file
329
apex/container_test.go
Normal file
@@ -0,0 +1,329 @@
|
|||||||
|
// Copyright 2024 Google Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package apex
|
||||||
|
|
||||||
|
import (
|
||||||
|
"android/soong/android"
|
||||||
|
"android/soong/java"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var checkContainerMatch = func(t *testing.T, name string, container string, expected bool, actual bool) {
|
||||||
|
errorMessage := fmt.Sprintf("module %s container %s value differ", name, container)
|
||||||
|
android.AssertBoolEquals(t, errorMessage, expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestApexDepsContainers(t *testing.T) {
|
||||||
|
result := android.GroupFixturePreparers(
|
||||||
|
prepareForApexTest,
|
||||||
|
java.PrepareForTestWithJavaSdkLibraryFiles,
|
||||||
|
java.FixtureWithLastReleaseApis("mybootclasspathlib"),
|
||||||
|
).RunTestWithBp(t, `
|
||||||
|
apex {
|
||||||
|
name: "myapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
bootclasspath_fragments: [
|
||||||
|
"mybootclasspathfragment",
|
||||||
|
],
|
||||||
|
updatable: true,
|
||||||
|
min_sdk_version: "30",
|
||||||
|
}
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
bootclasspath_fragment {
|
||||||
|
name: "mybootclasspathfragment",
|
||||||
|
contents: [
|
||||||
|
"mybootclasspathlib",
|
||||||
|
],
|
||||||
|
apex_available: [
|
||||||
|
"myapex",
|
||||||
|
],
|
||||||
|
hidden_api: {
|
||||||
|
split_packages: ["*"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
java_sdk_library {
|
||||||
|
name: "mybootclasspathlib",
|
||||||
|
srcs: [
|
||||||
|
"mybootclasspathlib.java",
|
||||||
|
],
|
||||||
|
apex_available: [
|
||||||
|
"myapex",
|
||||||
|
],
|
||||||
|
compile_dex: true,
|
||||||
|
static_libs: [
|
||||||
|
"foo",
|
||||||
|
"baz",
|
||||||
|
],
|
||||||
|
libs: [
|
||||||
|
"bar",
|
||||||
|
],
|
||||||
|
min_sdk_version: "30",
|
||||||
|
}
|
||||||
|
java_library {
|
||||||
|
name: "foo",
|
||||||
|
srcs:[
|
||||||
|
"A.java",
|
||||||
|
],
|
||||||
|
apex_available: [
|
||||||
|
"myapex",
|
||||||
|
],
|
||||||
|
min_sdk_version: "30",
|
||||||
|
}
|
||||||
|
java_library {
|
||||||
|
name: "bar",
|
||||||
|
srcs:[
|
||||||
|
"A.java",
|
||||||
|
],
|
||||||
|
min_sdk_version: "30",
|
||||||
|
}
|
||||||
|
java_library {
|
||||||
|
name: "baz",
|
||||||
|
srcs:[
|
||||||
|
"A.java",
|
||||||
|
],
|
||||||
|
apex_available: [
|
||||||
|
"//apex_available:platform",
|
||||||
|
"myapex",
|
||||||
|
],
|
||||||
|
min_sdk_version: "30",
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
testcases := []struct {
|
||||||
|
moduleName string
|
||||||
|
variant string
|
||||||
|
isSystemContainer bool
|
||||||
|
isApexContainer bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
moduleName: "mybootclasspathlib",
|
||||||
|
variant: "android_common_myapex",
|
||||||
|
isSystemContainer: true,
|
||||||
|
isApexContainer: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleName: "mybootclasspathlib.impl",
|
||||||
|
variant: "android_common_apex30",
|
||||||
|
isSystemContainer: true,
|
||||||
|
isApexContainer: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleName: "mybootclasspathlib.stubs",
|
||||||
|
variant: "android_common",
|
||||||
|
isSystemContainer: true,
|
||||||
|
isApexContainer: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleName: "foo",
|
||||||
|
variant: "android_common_apex30",
|
||||||
|
isSystemContainer: true,
|
||||||
|
isApexContainer: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleName: "bar",
|
||||||
|
variant: "android_common",
|
||||||
|
isSystemContainer: true,
|
||||||
|
isApexContainer: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleName: "baz",
|
||||||
|
variant: "android_common_apex30",
|
||||||
|
isSystemContainer: true,
|
||||||
|
isApexContainer: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range testcases {
|
||||||
|
m := result.ModuleForTests(c.moduleName, c.variant)
|
||||||
|
containers, _ := android.OtherModuleProvider(result.TestContext.OtherModuleProviderAdaptor(), m.Module(), android.ContainersInfoProvider)
|
||||||
|
belongingContainers := containers.BelongingContainers()
|
||||||
|
checkContainerMatch(t, c.moduleName, "system", c.isSystemContainer, android.InList(android.SystemContainer, belongingContainers))
|
||||||
|
checkContainerMatch(t, c.moduleName, "apex", c.isApexContainer, android.InList(android.ApexContainer, belongingContainers))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNonUpdatableApexDepsContainers(t *testing.T) {
|
||||||
|
result := android.GroupFixturePreparers(
|
||||||
|
prepareForApexTest,
|
||||||
|
java.PrepareForTestWithJavaSdkLibraryFiles,
|
||||||
|
java.FixtureWithLastReleaseApis("mybootclasspathlib"),
|
||||||
|
).RunTestWithBp(t, `
|
||||||
|
apex {
|
||||||
|
name: "myapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
bootclasspath_fragments: [
|
||||||
|
"mybootclasspathfragment",
|
||||||
|
],
|
||||||
|
updatable: false,
|
||||||
|
}
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
bootclasspath_fragment {
|
||||||
|
name: "mybootclasspathfragment",
|
||||||
|
contents: [
|
||||||
|
"mybootclasspathlib",
|
||||||
|
],
|
||||||
|
apex_available: [
|
||||||
|
"myapex",
|
||||||
|
],
|
||||||
|
hidden_api: {
|
||||||
|
split_packages: ["*"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
java_sdk_library {
|
||||||
|
name: "mybootclasspathlib",
|
||||||
|
srcs: [
|
||||||
|
"mybootclasspathlib.java",
|
||||||
|
],
|
||||||
|
apex_available: [
|
||||||
|
"myapex",
|
||||||
|
],
|
||||||
|
compile_dex: true,
|
||||||
|
static_libs: [
|
||||||
|
"foo",
|
||||||
|
],
|
||||||
|
libs: [
|
||||||
|
"bar",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
java_library {
|
||||||
|
name: "foo",
|
||||||
|
srcs:[
|
||||||
|
"A.java",
|
||||||
|
],
|
||||||
|
apex_available: [
|
||||||
|
"myapex",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
java_library {
|
||||||
|
name: "bar",
|
||||||
|
srcs:[
|
||||||
|
"A.java",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
testcases := []struct {
|
||||||
|
moduleName string
|
||||||
|
variant string
|
||||||
|
isSystemContainer bool
|
||||||
|
isApexContainer bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
moduleName: "mybootclasspathlib",
|
||||||
|
variant: "android_common_myapex",
|
||||||
|
isSystemContainer: true,
|
||||||
|
isApexContainer: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleName: "mybootclasspathlib.impl",
|
||||||
|
variant: "android_common_apex10000",
|
||||||
|
isSystemContainer: true,
|
||||||
|
isApexContainer: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleName: "mybootclasspathlib.stubs",
|
||||||
|
variant: "android_common",
|
||||||
|
isSystemContainer: true,
|
||||||
|
isApexContainer: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleName: "foo",
|
||||||
|
variant: "android_common_apex10000",
|
||||||
|
isSystemContainer: true,
|
||||||
|
isApexContainer: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleName: "bar",
|
||||||
|
variant: "android_common",
|
||||||
|
isSystemContainer: true,
|
||||||
|
isApexContainer: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range testcases {
|
||||||
|
m := result.ModuleForTests(c.moduleName, c.variant)
|
||||||
|
containers, _ := android.OtherModuleProvider(result.TestContext.OtherModuleProviderAdaptor(), m.Module(), android.ContainersInfoProvider)
|
||||||
|
belongingContainers := containers.BelongingContainers()
|
||||||
|
checkContainerMatch(t, c.moduleName, "system", c.isSystemContainer, android.InList(android.SystemContainer, belongingContainers))
|
||||||
|
checkContainerMatch(t, c.moduleName, "apex", c.isApexContainer, android.InList(android.ApexContainer, belongingContainers))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdatableAndNonUpdatableApexesIdenticalMinSdkVersion(t *testing.T) {
|
||||||
|
result := android.GroupFixturePreparers(
|
||||||
|
prepareForApexTest,
|
||||||
|
java.PrepareForTestWithJavaSdkLibraryFiles,
|
||||||
|
android.FixtureMergeMockFs(android.MockFS{
|
||||||
|
"system/sepolicy/apex/myapex_non_updatable-file_contexts": nil,
|
||||||
|
"system/sepolicy/apex/myapex_updatable-file_contexts": nil,
|
||||||
|
}),
|
||||||
|
).RunTestWithBp(t, `
|
||||||
|
apex {
|
||||||
|
name: "myapex_non_updatable",
|
||||||
|
key: "myapex_non_updatable.key",
|
||||||
|
java_libs: [
|
||||||
|
"foo",
|
||||||
|
],
|
||||||
|
updatable: false,
|
||||||
|
min_sdk_version: "30",
|
||||||
|
}
|
||||||
|
apex_key {
|
||||||
|
name: "myapex_non_updatable.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
apex {
|
||||||
|
name: "myapex_updatable",
|
||||||
|
key: "myapex_updatable.key",
|
||||||
|
java_libs: [
|
||||||
|
"foo",
|
||||||
|
],
|
||||||
|
updatable: true,
|
||||||
|
min_sdk_version: "30",
|
||||||
|
}
|
||||||
|
apex_key {
|
||||||
|
name: "myapex_updatable.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
java_library {
|
||||||
|
name: "foo",
|
||||||
|
srcs:[
|
||||||
|
"A.java",
|
||||||
|
],
|
||||||
|
apex_available: [
|
||||||
|
"myapex_non_updatable",
|
||||||
|
"myapex_updatable",
|
||||||
|
],
|
||||||
|
min_sdk_version: "30",
|
||||||
|
sdk_version: "current",
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
fooApexVariant := result.ModuleForTests("foo", "android_common_apex30")
|
||||||
|
containers, _ := android.OtherModuleProvider(result.TestContext.OtherModuleProviderAdaptor(), fooApexVariant.Module(), android.ContainersInfoProvider)
|
||||||
|
belongingContainers := containers.BelongingContainers()
|
||||||
|
checkContainerMatch(t, "foo", "system", true, android.InList(android.SystemContainer, belongingContainers))
|
||||||
|
checkContainerMatch(t, "foo", "apex", true, android.InList(android.ApexContainer, belongingContainers))
|
||||||
|
}
|
@@ -87,6 +87,7 @@ bootstrap_go_package {
|
|||||||
"app_set_test.go",
|
"app_set_test.go",
|
||||||
"app_test.go",
|
"app_test.go",
|
||||||
"code_metadata_test.go",
|
"code_metadata_test.go",
|
||||||
|
"container_test.go",
|
||||||
"bootclasspath_fragment_test.go",
|
"bootclasspath_fragment_test.go",
|
||||||
"device_host_converter_test.go",
|
"device_host_converter_test.go",
|
||||||
"dex_test.go",
|
"dex_test.go",
|
||||||
|
12
java/base.go
12
java/base.go
@@ -552,6 +552,18 @@ type Module struct {
|
|||||||
aconfigCacheFiles android.Paths
|
aconfigCacheFiles android.Paths
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ android.InstallableModule = (*Module)(nil)
|
||||||
|
|
||||||
|
// To satisfy the InstallableModule interface
|
||||||
|
func (j *Module) EnforceApiContainerChecks() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overrides android.ModuleBase.InstallInProduct()
|
||||||
|
func (j *Module) InstallInProduct() bool {
|
||||||
|
return j.ProductSpecific()
|
||||||
|
}
|
||||||
|
|
||||||
func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
|
func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
|
||||||
sdkVersion := j.SdkVersion(ctx)
|
sdkVersion := j.SdkVersion(ctx)
|
||||||
if sdkVersion.Stable() {
|
if sdkVersion.Stable() {
|
||||||
|
129
java/container_test.go
Normal file
129
java/container_test.go
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
// Copyright 2024 Google Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package java
|
||||||
|
|
||||||
|
import (
|
||||||
|
"android/soong/android"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var checkContainerMatch = func(t *testing.T, name string, container string, expected bool, actual bool) {
|
||||||
|
errorMessage := fmt.Sprintf("module %s container %s value differ", name, container)
|
||||||
|
android.AssertBoolEquals(t, errorMessage, expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJavaContainersModuleProperties(t *testing.T) {
|
||||||
|
result := android.GroupFixturePreparers(
|
||||||
|
prepareForJavaTest,
|
||||||
|
).RunTestWithBp(t, `
|
||||||
|
java_library {
|
||||||
|
name: "foo",
|
||||||
|
srcs: ["A.java"],
|
||||||
|
}
|
||||||
|
java_library {
|
||||||
|
name: "foo_vendor",
|
||||||
|
srcs: ["A.java"],
|
||||||
|
vendor: true,
|
||||||
|
sdk_version: "current",
|
||||||
|
}
|
||||||
|
java_library {
|
||||||
|
name: "foo_soc_specific",
|
||||||
|
srcs: ["A.java"],
|
||||||
|
soc_specific: true,
|
||||||
|
sdk_version: "current",
|
||||||
|
}
|
||||||
|
java_library {
|
||||||
|
name: "foo_product_specific",
|
||||||
|
srcs: ["A.java"],
|
||||||
|
product_specific: true,
|
||||||
|
sdk_version: "current",
|
||||||
|
}
|
||||||
|
java_test {
|
||||||
|
name: "foo_cts_test",
|
||||||
|
srcs: ["A.java"],
|
||||||
|
test_suites: [
|
||||||
|
"cts",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
java_test {
|
||||||
|
name: "foo_non_cts_test",
|
||||||
|
srcs: ["A.java"],
|
||||||
|
test_suites: [
|
||||||
|
"general-tests",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
testcases := []struct {
|
||||||
|
moduleName string
|
||||||
|
isSystemContainer bool
|
||||||
|
isVendorContainer bool
|
||||||
|
isProductContainer bool
|
||||||
|
isCts bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
moduleName: "foo",
|
||||||
|
isSystemContainer: true,
|
||||||
|
isVendorContainer: false,
|
||||||
|
isProductContainer: false,
|
||||||
|
isCts: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleName: "foo_vendor",
|
||||||
|
isSystemContainer: false,
|
||||||
|
isVendorContainer: true,
|
||||||
|
isProductContainer: false,
|
||||||
|
isCts: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleName: "foo_soc_specific",
|
||||||
|
isSystemContainer: false,
|
||||||
|
isVendorContainer: true,
|
||||||
|
isProductContainer: false,
|
||||||
|
isCts: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleName: "foo_product_specific",
|
||||||
|
isSystemContainer: false,
|
||||||
|
isVendorContainer: false,
|
||||||
|
isProductContainer: true,
|
||||||
|
isCts: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleName: "foo_cts_test",
|
||||||
|
isSystemContainer: false,
|
||||||
|
isVendorContainer: false,
|
||||||
|
isProductContainer: false,
|
||||||
|
isCts: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleName: "foo_non_cts_test",
|
||||||
|
isSystemContainer: false,
|
||||||
|
isVendorContainer: false,
|
||||||
|
isProductContainer: false,
|
||||||
|
isCts: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range testcases {
|
||||||
|
m := result.ModuleForTests(c.moduleName, "android_common")
|
||||||
|
containers, _ := android.OtherModuleProvider(result.TestContext.OtherModuleProviderAdaptor(), m.Module(), android.ContainersInfoProvider)
|
||||||
|
belongingContainers := containers.BelongingContainers()
|
||||||
|
checkContainerMatch(t, c.moduleName, "system", c.isSystemContainer, android.InList(android.SystemContainer, belongingContainers))
|
||||||
|
checkContainerMatch(t, c.moduleName, "vendor", c.isVendorContainer, android.InList(android.VendorContainer, belongingContainers))
|
||||||
|
checkContainerMatch(t, c.moduleName, "product", c.isProductContainer, android.InList(android.ProductContainer, belongingContainers))
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user