From 2f791a246bf608d9356c6ef5e8cb3cd19a0d219d Mon Sep 17 00:00:00 2001 From: Inseob Kim Date: Tue, 30 Jul 2019 17:55:33 +0900 Subject: [PATCH] Implement sysprop_library API stability check sysprop_library now checks the API stability itself, cutting dependency on java_sdk_library. Under the directory {module_dir}/api, {module_name}-current.txt and {module_name}-latest.txt hold API signatures. When sysprop_library is built, or a user run "m {module_name}-check-api" command, API check is performed. First, current.txt must have exactly same signature with built sysprop_library module. Second, current.txt must be compatible with latest.txt. Build system emits a handy error message to generate/update those API files, in case of missing or mismatching. Also, a script file for freezing API files is introduced. Bug: 131637873 Test: 1) m && boot blueline Test: 2) m {sysprop_library} performs API check Test: 3) manual test for check-api, freezing api Change-Id: I9d25f5dc64299e666527ca8e23d7233966901c4e Merged-In: I9d25f5dc64299e666527ca8e23d7233966901c4e (cherry picked from commit 093f0eb1331dffaab23e9252d2a4dbc6a27156f0) --- cc/library.go | 4 +- cc/sysprop.go | 3 +- java/droiddoc.go | 3 - java/gen.go | 31 +++- java/java.go | 5 +- scripts/freeze-sysprop-api-files.sh | 39 +++++ scripts/gen-sysprop-api-files.sh | 26 ++++ sysprop/sysprop_library.go | 221 ++++++++++++++++++++++++---- sysprop/sysprop_test.go | 99 ++++++------- 9 files changed, 341 insertions(+), 90 deletions(-) create mode 100755 scripts/freeze-sysprop-api-files.sh create mode 100755 scripts/gen-sysprop-api-files.sh diff --git a/cc/library.go b/cc/library.go index 0869727fc..fe15892d3 100644 --- a/cc/library.go +++ b/cc/library.go @@ -937,9 +937,7 @@ func (library *libraryDecorator) link(ctx ModuleContext, isVendor := ctx.useVndk() isOwnerPlatform := Bool(library.Properties.Sysprop.Platform) - usePublic := isProduct || (isOwnerPlatform == isVendor) - - if usePublic { + if !ctx.inRecovery() && (isProduct || (isOwnerPlatform == isVendor)) { dir = android.PathForModuleGen(ctx, "sysprop/public", "include").String() } } diff --git a/cc/sysprop.go b/cc/sysprop.go index 656f79f59..6cac7fb10 100644 --- a/cc/sysprop.go +++ b/cc/sysprop.go @@ -21,6 +21,7 @@ import ( ) type syspropLibraryInterface interface { + BaseModuleName() string CcModuleName() string } @@ -42,6 +43,6 @@ func SyspropMutator(mctx android.BottomUpMutatorContext) { syspropImplLibrariesLock.Lock() defer syspropImplLibrariesLock.Unlock() - syspropImplLibraries[mctx.ModuleName()] = m.CcModuleName() + syspropImplLibraries[m.BaseModuleName()] = m.CcModuleName() } } diff --git a/java/droiddoc.go b/java/droiddoc.go index 9956270c9..4caee3649 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -484,9 +484,6 @@ func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths, case ".aidl": javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps) outSrcFiles = append(outSrcFiles, javaFile) - case ".sysprop": - javaFile := genSysprop(ctx, srcFile) - outSrcFiles = append(outSrcFiles, javaFile) default: outSrcFiles = append(outSrcFiles, srcFile) } diff --git a/java/gen.go b/java/gen.go index 69965ecec..81fc3417f 100644 --- a/java/gen.go +++ b/java/gen.go @@ -53,13 +53,13 @@ var ( sysprop = pctx.AndroidStaticRule("sysprop", blueprint.RuleParams{ Command: `rm -rf $out.tmp && mkdir -p $out.tmp && ` + - `$syspropCmd --java-output-dir $out.tmp $in && ` + + `$syspropCmd --scope $scope --java-output-dir $out.tmp $in && ` + `${config.SoongZipCmd} -jar -o $out -C $out.tmp -D $out.tmp && rm -rf $out.tmp`, CommandDeps: []string{ "$syspropCmd", "${config.SoongZipCmd}", }, - }) + }, "scope") ) func genAidl(ctx android.ModuleContext, aidlFile android.Path, aidlFlags string, deps android.Paths) android.Path { @@ -98,7 +98,7 @@ func genLogtags(ctx android.ModuleContext, logtagsFile android.Path) android.Pat return javaFile } -func genSysprop(ctx android.ModuleContext, syspropFile android.Path) android.Path { +func genSysprop(ctx android.ModuleContext, syspropFile android.Path, scope string) android.Path { srcJarFile := android.GenPathWithExt(ctx, "sysprop", syspropFile, "srcjar") ctx.Build(pctx, android.BuildParams{ @@ -106,6 +106,9 @@ func genSysprop(ctx android.ModuleContext, syspropFile android.Path) android.Pat Description: "sysprop_java " + syspropFile.Rel(), Output: srcJarFile, Input: syspropFile, + Args: map[string]string{ + "scope": scope, + }, }) return srcJarFile @@ -129,7 +132,27 @@ func (j *Module) genSources(ctx android.ModuleContext, srcFiles android.Paths, srcJarFile := genProto(ctx, srcFile, flags.proto) outSrcFiles = append(outSrcFiles, srcJarFile) case ".sysprop": - srcJarFile := genSysprop(ctx, srcFile) + // internal scope contains all properties + // public scope only contains public properties + // use public if the owner is different from client + scope := "internal" + if j.properties.Sysprop.Platform != nil { + isProduct := ctx.ProductSpecific() + isVendor := ctx.SocSpecific() + isOwnerPlatform := Bool(j.properties.Sysprop.Platform) + + if isProduct { + // product can't own any sysprop_library now, so product must use public scope + scope = "public" + } else if isVendor && !isOwnerPlatform { + // vendor and odm can't use system's internal property. + scope = "public" + } + + // We don't care about clients under system. + // They can't use sysprop_library owned by other partitions. + } + srcJarFile := genSysprop(ctx, srcFile, scope) outSrcFiles = append(outSrcFiles, srcJarFile) default: outSrcFiles = append(outSrcFiles, srcFile) diff --git a/java/java.go b/java/java.go index afb121871..2193a2bd7 100644 --- a/java/java.go +++ b/java/java.go @@ -183,6 +183,10 @@ type CompilerProperties struct { Output_params []string } + Sysprop struct { + Platform *bool + } `blueprint:"mutated"` + Instrument bool `blueprint:"mutated"` // List of files to include in the META-INF/services folder of the resulting jar. @@ -1017,7 +1021,6 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB } func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { - j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs) deps := j.collectDeps(ctx) diff --git a/scripts/freeze-sysprop-api-files.sh b/scripts/freeze-sysprop-api-files.sh new file mode 100755 index 000000000..1b2ff7c72 --- /dev/null +++ b/scripts/freeze-sysprop-api-files.sh @@ -0,0 +1,39 @@ +#!/bin/bash -e + +# Copyright (C) 2019 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. + +# This script freezes APIs of a sysprop_library after checking compatibility +# between latest API and current API. +# +# Usage: freeze-sysprop-api-files.sh +# +# : the directory, either relative or absolute, which holds the +# Android.bp file defining sysprop_library. +# +# : the name of sysprop_library to freeze API. +# +# Example: +# $ . build/envsetup.sh && lunch aosp_arm64-user +# $ . build/soong/scripts/freeze-sysprop-api-files.sh \ +# system/libsysprop/srcs PlatformProperties + +if [[ -z "$1" || -z "$2" ]]; then + echo "usage: $0 " >&2 + exit 1 +fi + +api_dir=$1/api + +m "$2-check-api" && cp -f "${api_dir}/$2-current.txt" "${api_dir}/$2-latest.txt" diff --git a/scripts/gen-sysprop-api-files.sh b/scripts/gen-sysprop-api-files.sh new file mode 100755 index 000000000..a4cb50649 --- /dev/null +++ b/scripts/gen-sysprop-api-files.sh @@ -0,0 +1,26 @@ +#!/bin/bash -e + +# Copyright (C) 2019 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. + +if [[ -z "$1" || -z "$2" ]]; then + echo "usage: $0 " >&2 + exit 1 +fi + +api_dir=$1/api + +mkdir -p "$api_dir" +touch "${api_dir}/$2-current.txt" +touch "${api_dir}/$2-latest.txt" diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go index 86061c6a2..c7669bd9d 100644 --- a/sysprop/sysprop_library.go +++ b/sysprop/sysprop_library.go @@ -15,12 +15,16 @@ package sysprop import ( - "android/soong/android" - "android/soong/cc" - "android/soong/java" + "fmt" + "io" + "path" "github.com/google/blueprint" "github.com/google/blueprint/proptools" + + "android/soong/android" + "android/soong/cc" + "android/soong/java" ) type dependencyTag struct { @@ -29,10 +33,14 @@ type dependencyTag struct { } type syspropLibrary struct { - java.SdkLibrary + android.ModuleBase - commonProperties commonProperties - syspropLibraryProperties syspropLibraryProperties + properties syspropLibraryProperties + + checkApiFileTimeStamp android.WritablePath + latestApiFile android.Path + currentApiFile android.Path + dumpedApiFile android.WritablePath } type syspropLibraryProperties struct { @@ -42,17 +50,22 @@ type syspropLibraryProperties struct { // list of package names that will be documented and publicized as API Api_packages []string -} -type commonProperties struct { - Srcs []string - Recovery *bool + // If set to true, allow this module to be dexed and installed on devices. + Installable *bool + + // Make this module available when building for recovery Recovery_available *bool - Vendor_available *bool + + // Make this module available when building for vendor + Vendor_available *bool + + // list of .sysprop files which defines the properties. + Srcs []string `android:"path"` } var ( - Bool = proptools.Bool + pctx = android.NewPackageContext("android/soong/sysprop") syspropCcTag = dependencyTag{name: "syspropCc"} ) @@ -60,56 +73,166 @@ func init() { android.RegisterModuleType("sysprop_library", syspropLibraryFactory) } -func (m *syspropLibrary) CcModuleName() string { - return "lib" + m.Name() +func (m *syspropLibrary) Name() string { + return m.BaseModuleName() + "_sysprop_library" } +func (m *syspropLibrary) CcModuleName() string { + return "lib" + m.BaseModuleName() +} + +func (m *syspropLibrary) BaseModuleName() string { + return m.ModuleBase.Name() +} + +func (m *syspropLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { + m.currentApiFile = android.PathForSource(ctx, ctx.ModuleDir(), "api", m.BaseModuleName()+"-current.txt") + m.latestApiFile = android.PathForSource(ctx, ctx.ModuleDir(), "api", m.BaseModuleName()+"-latest.txt") + + // dump API rule + rule := android.NewRuleBuilder() + m.dumpedApiFile = android.PathForModuleOut(ctx, "api-dump.txt") + rule.Command(). + BuiltTool(ctx, "sysprop_api_dump"). + Output(m.dumpedApiFile). + Inputs(android.PathsForModuleSrc(ctx, m.properties.Srcs)) + rule.Build(pctx, ctx, m.BaseModuleName()+"_api_dump", m.BaseModuleName()+" api dump") + + // check API rule + rule = android.NewRuleBuilder() + + // 1. current.txt <-> api_dump.txt + msg := fmt.Sprintf(`\n******************************\n`+ + `API of sysprop_library %s doesn't match with current.txt\n`+ + `Please update current.txt by:\n`+ + `rm -rf %q && cp -f %q %q\n`+ + `******************************\n`, m.BaseModuleName(), + m.currentApiFile.String(), m.dumpedApiFile.String(), m.currentApiFile.String()) + + rule.Command(). + Text("( cmp").Flag("-s"). + Input(m.dumpedApiFile). + Input(m.currentApiFile). + Text("|| ( echo").Flag("-e"). + Flag(`"` + msg + `"`). + Text("; exit 38) )") + + // 2. current.txt <-> latest.txt + msg = fmt.Sprintf(`\n******************************\n`+ + `API of sysprop_library %s doesn't match with latest version\n`+ + `Please fix the breakage and rebuild.\n`+ + `******************************\n`, m.BaseModuleName()) + + rule.Command(). + Text("( "). + BuiltTool(ctx, "sysprop_api_checker"). + Input(m.latestApiFile). + Input(m.currentApiFile). + Text(" || ( echo").Flag("-e"). + Flag(`"` + msg + `"`). + Text("; exit 38) )") + + m.checkApiFileTimeStamp = android.PathForModuleOut(ctx, "check_api.timestamp") + + rule.Command(). + Text("touch"). + Output(m.checkApiFileTimeStamp) + + rule.Build(pctx, ctx, m.BaseModuleName()+"_check_api", m.BaseModuleName()+" check api") +} + +func (m *syspropLibrary) AndroidMk() android.AndroidMkData { + return android.AndroidMkData{ + Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) { + // sysprop_library module itself is defined as a FAKE module to perform API check. + // Actual implementation libraries are created on LoadHookMutator + fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)") + fmt.Fprintf(w, "LOCAL_MODULE := %s\n", m.Name()) + fmt.Fprintf(w, "LOCAL_MODULE_CLASS := FAKE\n") + fmt.Fprintf(w, "LOCAL_MODULE_TAGS := optional\n") + fmt.Fprintf(w, "include $(BUILD_SYSTEM)/base_rules.mk\n\n") + fmt.Fprintf(w, "$(LOCAL_BUILT_MODULE): %s\n", m.checkApiFileTimeStamp.String()) + fmt.Fprintf(w, "\ttouch $@\n\n") + fmt.Fprintf(w, ".PHONY: %s-check-api\n\n", name) + + // check API rule + fmt.Fprintf(w, "%s-check-api: %s\n\n", name, m.checkApiFileTimeStamp.String()) + + // "make {sysprop_library}" should also build the C++ library + fmt.Fprintf(w, "%s: %s\n\n", name, m.CcModuleName()) + }} +} + +// sysprop_library creates schematized APIs from sysprop description files (.sysprop). +// Both Java and C++ modules can link against sysprop_library, and API stability check +// against latest APIs (see build/soong/scripts/freeze-sysprop-api-files.sh) +// is performed. func syspropLibraryFactory() android.Module { m := &syspropLibrary{} m.AddProperties( - &m.commonProperties, - &m.syspropLibraryProperties, + &m.properties, ) - m.InitSdkLibraryProperties() - m.SetNoDist() - android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, "common") + android.InitAndroidModule(m) android.AddLoadHook(m, func(ctx android.LoadHookContext) { syspropLibraryHook(ctx, m) }) - android.AddLoadHook(m, func(ctx android.LoadHookContext) { m.SdkLibrary.CreateInternalModules(ctx) }) return m } func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) { - if len(m.commonProperties.Srcs) == 0 { + if len(m.properties.Srcs) == 0 { ctx.PropertyErrorf("srcs", "sysprop_library must specify srcs") } - if len(m.syspropLibraryProperties.Api_packages) == 0 { - ctx.PropertyErrorf("api_packages", "sysprop_library must specify api_packages") + missing_api := false + + for _, txt := range []string{"-current.txt", "-latest.txt"} { + path := path.Join(ctx.ModuleDir(), "api", m.BaseModuleName()+txt) + file := android.ExistentPathForSource(ctx, path) + if !file.Valid() { + ctx.ModuleErrorf("API file %#v doesn't exist", path) + missing_api = true + } + } + + if missing_api { + script := "build/soong/scripts/gen-sysprop-api-files.sh" + p := android.ExistentPathForSource(ctx, script) + + if !p.Valid() { + panic(fmt.Sprintf("script file %s doesn't exist", script)) + } + + ctx.ModuleErrorf("One or more api files are missing. "+ + "You can create them by:\n"+ + "%s %q %q", script, ctx.ModuleDir(), m.BaseModuleName()) + return } socSpecific := ctx.SocSpecific() deviceSpecific := ctx.DeviceSpecific() productSpecific := ctx.ProductSpecific() - owner := m.syspropLibraryProperties.Property_owner + owner := m.properties.Property_owner + stub := "sysprop-library-stub-" switch owner { case "Platform": // Every partition can access platform-defined properties - break + stub += "platform" case "Vendor": // System can't access vendor's properties if !socSpecific && !deviceSpecific && !productSpecific { ctx.ModuleErrorf("None of soc_specific, device_specific, product_specific is true. " + "System can't access sysprop_library owned by Vendor") } + stub += "vendor" case "Odm": // Only vendor can access Odm-defined properties if !socSpecific && !deviceSpecific { ctx.ModuleErrorf("Neither soc_speicifc nor device_specific is true. " + "Odm-defined properties should be accessed only in Vendor or Odm") } + stub += "vendor" default: ctx.PropertyErrorf("property_owner", "Unknown value %s: must be one of Platform, Vendor or Odm", owner) @@ -117,17 +240,23 @@ func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) { ccProps := struct { Name *string + Srcs []string Soc_specific *bool Device_specific *bool Product_specific *bool Sysprop struct { Platform *bool } - Header_libs []string - Shared_libs []string + Header_libs []string + Shared_libs []string + Required []string + Recovery *bool + Recovery_available *bool + Vendor_available *bool }{} ccProps.Name = proptools.StringPtr(m.CcModuleName()) + ccProps.Srcs = m.properties.Srcs ccProps.Soc_specific = proptools.BoolPtr(socSpecific) ccProps.Device_specific = proptools.BoolPtr(deviceSpecific) ccProps.Product_specific = proptools.BoolPtr(productSpecific) @@ -135,5 +264,41 @@ func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) { ccProps.Header_libs = []string{"libbase_headers"} ccProps.Shared_libs = []string{"liblog"} - ctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &m.commonProperties, &ccProps) + // add sysprop_library module to perform check API + ccProps.Required = []string{m.Name()} + ccProps.Sysprop.Platform = proptools.BoolPtr(owner == "Platform") + ccProps.Recovery_available = m.properties.Recovery_available + ccProps.Vendor_available = m.properties.Vendor_available + + ctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &ccProps) + + javaProps := struct { + Name *string + Srcs []string + Soc_specific *bool + Device_specific *bool + Product_specific *bool + Sysprop struct { + Platform *bool + } + Required []string + Sdk_version *string + Installable *bool + Libs []string + }{} + + javaProps.Name = proptools.StringPtr(m.BaseModuleName()) + javaProps.Srcs = m.properties.Srcs + javaProps.Soc_specific = proptools.BoolPtr(socSpecific) + javaProps.Device_specific = proptools.BoolPtr(deviceSpecific) + javaProps.Product_specific = proptools.BoolPtr(productSpecific) + javaProps.Installable = m.properties.Installable + + // add sysprop_library module to perform check API + javaProps.Required = []string{m.Name()} + javaProps.Sdk_version = proptools.StringPtr("core_current") + javaProps.Sysprop.Platform = proptools.BoolPtr(owner == "Platform") + javaProps.Libs = []string{stub} + + ctx.CreateModule(android.ModuleFactoryAdaptor(java.LibraryFactory), &javaProps) } diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go index 0566036a2..5345770a8 100644 --- a/sysprop/sysprop_test.go +++ b/sysprop/sysprop_test.go @@ -57,16 +57,11 @@ func testContext(config android.Config, bp string, ctx := android.NewTestArchContext() ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(java.AndroidAppFactory)) - ctx.RegisterModuleType("droiddoc_template", android.ModuleFactoryAdaptor(java.ExportedDroiddocDirFactory)) ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(java.LibraryFactory)) ctx.RegisterModuleType("java_system_modules", android.ModuleFactoryAdaptor(java.SystemModulesFactory)) - ctx.RegisterModuleType("prebuilt_apis", android.ModuleFactoryAdaptor(java.PrebuiltApisFactory)) ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators) ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators) ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) - ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) { - ctx.TopDown("prebuilt_apis", java.PrebuiltApisMutator).Parallel() - }) ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory)) ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(cc.LibraryHeaderFactory)) @@ -91,45 +86,20 @@ func testContext(config android.Config, bp string, bp += cc.GatherRequiredDepsForTest(android.Android) mockFS := map[string][]byte{ - "Android.bp": []byte(bp), - "a.java": nil, - "b.java": nil, - "c.java": nil, - "d.cpp": nil, - "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, - "framework/aidl/a.aidl": nil, - - "prebuilts/sdk/current/core/android.jar": nil, - "prebuilts/sdk/current/public/android.jar": nil, - "prebuilts/sdk/current/public/framework.aidl": nil, - "prebuilts/sdk/current/public/core.jar": nil, - "prebuilts/sdk/current/system/android.jar": nil, - "prebuilts/sdk/current/test/android.jar": nil, - "prebuilts/sdk/28/public/api/sysprop-platform.txt": nil, - "prebuilts/sdk/28/system/api/sysprop-platform.txt": nil, - "prebuilts/sdk/28/test/api/sysprop-platform.txt": nil, - "prebuilts/sdk/28/public/api/sysprop-platform-removed.txt": nil, - "prebuilts/sdk/28/system/api/sysprop-platform-removed.txt": nil, - "prebuilts/sdk/28/test/api/sysprop-platform-removed.txt": nil, - "prebuilts/sdk/28/public/api/sysprop-platform-on-product.txt": nil, - "prebuilts/sdk/28/system/api/sysprop-platform-on-product.txt": nil, - "prebuilts/sdk/28/test/api/sysprop-platform-on-product.txt": nil, - "prebuilts/sdk/28/public/api/sysprop-platform-on-product-removed.txt": nil, - "prebuilts/sdk/28/system/api/sysprop-platform-on-product-removed.txt": nil, - "prebuilts/sdk/28/test/api/sysprop-platform-on-product-removed.txt": nil, - "prebuilts/sdk/28/public/api/sysprop-vendor.txt": nil, - "prebuilts/sdk/28/system/api/sysprop-vendor.txt": nil, - "prebuilts/sdk/28/test/api/sysprop-vendor.txt": nil, - "prebuilts/sdk/28/public/api/sysprop-vendor-removed.txt": nil, - "prebuilts/sdk/28/system/api/sysprop-vendor-removed.txt": nil, - "prebuilts/sdk/28/test/api/sysprop-vendor-removed.txt": nil, - "prebuilts/sdk/tools/core-lambda-stubs.jar": nil, - "prebuilts/sdk/Android.bp": []byte(`prebuilt_apis { name: "sdk", api_dirs: ["28", "current"],}`), + "Android.bp": []byte(bp), + "a.java": nil, + "b.java": nil, + "c.java": nil, + "d.cpp": nil, + "api/sysprop-platform-current.txt": nil, + "api/sysprop-platform-latest.txt": nil, + "api/sysprop-platform-on-product-current.txt": nil, + "api/sysprop-platform-on-product-latest.txt": nil, + "api/sysprop-vendor-current.txt": nil, + "api/sysprop-vendor-latest.txt": nil, + "api/sysprop-odm-current.txt": nil, + "api/sysprop-odm-latest.txt": nil, + "framework/aidl/a.aidl": nil, // For framework-res, which is an implicit dependency for framework "AndroidManifest.xml": nil, @@ -155,6 +125,7 @@ func testContext(config android.Config, bp string, "android/sysprop/PlatformProperties.sysprop": nil, "com/android/VendorProperties.sysprop": nil, + "com/android2/OdmProperties.sysprop": nil, } for k, v := range fs { @@ -168,7 +139,7 @@ func testContext(config android.Config, bp string, func run(t *testing.T, ctx *android.TestContext, config android.Config) { t.Helper() - _, errs := ctx.ParseFileList(".", []string{"Android.bp", "prebuilts/sdk/Android.bp"}) + _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) android.FailIfErrored(t, errs) _, errs = ctx.PrepareBuildActions(config) android.FailIfErrored(t, errs) @@ -221,6 +192,14 @@ func TestSyspropLibrary(t *testing.T) { vendor_available: true, } + sysprop_library { + name: "sysprop-odm", + srcs: ["com/android2/OdmProperties.sysprop"], + api_packages: ["com.android2"], + property_owner: "Odm", + device_specific: true, + } + java_library { name: "java-platform", srcs: ["c.java"], @@ -288,20 +267,40 @@ func TestSyspropLibrary(t *testing.T) { name: "liblog", symbol_file: "", } + + java_library { + name: "sysprop-library-stub-platform", + sdk_version: "core_current", + } + + java_library { + name: "sysprop-library-stub-vendor", + soc_specific: true, + sdk_version: "core_current", + } `) + // Check for generated cc_library + for _, variant := range []string{ + "android_arm_armv7-a-neon_vendor_shared", + "android_arm_armv7-a-neon_vendor_static", + "android_arm64_armv8-a_vendor_shared", + "android_arm64_armv8-a_vendor_static", + } { + ctx.ModuleForTests("libsysprop-platform", variant) + ctx.ModuleForTests("libsysprop-vendor", variant) + ctx.ModuleForTests("libsysprop-odm", variant) + } + for _, variant := range []string{ "android_arm_armv7-a-neon_core_shared", "android_arm_armv7-a-neon_core_static", - "android_arm_armv7-a-neon_vendor_shared", - "android_arm_armv7-a-neon_vendor_static", "android_arm64_armv8-a_core_shared", "android_arm64_armv8-a_core_static", - "android_arm64_armv8-a_vendor_shared", - "android_arm64_armv8-a_vendor_static", } { - // Check for generated cc_library ctx.ModuleForTests("libsysprop-platform", variant) + + // core variant of vendor-owned sysprop_library is for product ctx.ModuleForTests("libsysprop-vendor", variant) }