apex: Restrict usage of "use_vendor"

When use_vendor is used, native modules are built with
__ANDROID_VNDK__ and __ANDROID_APEX__, which may cause
compatibility issues. (e.g. libbinder)

Even though libbinder restricts its availability via
'apex_available' property and relies on yet another macro
__ANDROID_APEX_<NAME>__, we restrict usage of "use_vendor:" from
other APEX modules to avoid similar problems.

Bug: 142684427
Test: m -j
Change-Id: Ibc781de2efcd20cb6688a183b08e908a8a6e2593
This commit is contained in:
Jooyung Han
2019-11-01 03:14:38 +09:00
parent 61eb8aaea4
commit dc782449b8
2 changed files with 73 additions and 4 deletions

View File

@@ -333,6 +333,34 @@ func apexUsesMutator(mctx android.BottomUpMutatorContext) {
}
}
var (
useVendorWhitelistKey = android.NewOnceKey("useVendorWhitelist")
)
// useVendorWhitelist returns the list of APEXes which are allowed to use_vendor.
// When use_vendor is used, native modules are built with __ANDROID_VNDK__ and __ANDROID_APEX__,
// which may cause compatibility issues. (e.g. libbinder)
// Even though libbinder restricts its availability via 'apex_available' property and relies on
// yet another macro __ANDROID_APEX_<NAME>__, we restrict usage of "use_vendor:" from other APEX modules
// to avoid similar problems.
func useVendorWhitelist(config android.Config) []string {
return config.Once(useVendorWhitelistKey, func() interface{} {
return []string{
// swcodec uses "vendor" variants for smaller size
"com.android.media.swcodec",
"test_com.android.media.swcodec",
}
}).([]string)
}
// setUseVendorWhitelistForTest overrides useVendorWhitelist and must be
// called before the first call to useVendorWhitelist()
func setUseVendorWhitelistForTest(config android.Config, whitelist []string) {
config.Once(useVendorWhitelistKey, func() interface{} {
return whitelist
})
}
type apexNativeDependencies struct {
// List of native libraries
Native_shared_libs []string
@@ -661,6 +689,10 @@ func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
}
func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
if proptools.Bool(a.properties.Use_vendor) && !android.InList(a.Name(), useVendorWhitelist(ctx.Config())) {
ctx.PropertyErrorf("use_vendor", "not allowed to set use_vendor: true")
}
targets := ctx.MultiTargets()
config := ctx.DeviceConfig()

View File

@@ -818,8 +818,9 @@ func TestApexDependencyToLLNDK(t *testing.T) {
name: "libbar",
symbol_file: "",
}
`)
`, func(fs map[string][]byte, config android.Config) {
setUseVendorWhitelistForTest(config, []string{"myapex"})
})
apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
@@ -1047,7 +1048,9 @@ func TestUseVendor(t *testing.T) {
vendor_available: true,
stl: "none",
}
`)
`, func(fs map[string][]byte, config android.Config) {
setUseVendorWhitelistForTest(config, []string{"myapex"})
})
inputsList := []string{}
for _, i := range ctx.ModuleForTests("myapex", "android_common_myapex").Module().BuildParamsForTests() {
@@ -1066,6 +1069,38 @@ func TestUseVendor(t *testing.T) {
ensureNotContains(t, inputsString, "android_arm64_armv8-a_core_shared_myapex/mylib2.so")
}
func TestUseVendorRestriction(t *testing.T) {
testApexError(t, `module "myapex" .*: use_vendor: not allowed`, `
apex {
name: "myapex",
key: "myapex.key",
use_vendor: true,
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
`, func(fs map[string][]byte, config android.Config) {
setUseVendorWhitelistForTest(config, []string{""})
})
// no error with whitelist
testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
use_vendor: true,
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
`, func(fs map[string][]byte, config android.Config) {
setUseVendorWhitelistForTest(config, []string{"myapex"})
})
}
func TestUseVendorFailsIfNotVendorAvailable(t *testing.T) {
testApexError(t, `dependency "mylib" of "myapex" missing variant:\n.*image:vendor`, `
apex {
@@ -2356,7 +2391,9 @@ func TestApexUsesFailsIfUseVenderMismatch(t *testing.T) {
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
`)
`, func(fs map[string][]byte, config android.Config) {
setUseVendorWhitelistForTest(config, []string{"myapex"})
})
}
func TestErrorsIfDepsAreNotEnabled(t *testing.T) {