Merge "We have md5sum/sha1sum/sha256sum/sha512sum on Darwin now too."
diff --git a/cc/library.go b/cc/library.go
index 2496712..6564fa1 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -952,9 +952,7 @@
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 656f79f..6cac7fb 100644
--- a/cc/sysprop.go
+++ b/cc/sysprop.go
@@ -21,6 +21,7 @@
)
type syspropLibraryInterface interface {
+ BaseModuleName() string
CcModuleName() string
}
@@ -42,6 +43,6 @@
syspropImplLibrariesLock.Lock()
defer syspropImplLibrariesLock.Unlock()
- syspropImplLibraries[mctx.ModuleName()] = m.CcModuleName()
+ syspropImplLibraries[m.BaseModuleName()] = m.CcModuleName()
}
}
diff --git a/java/app.go b/java/app.go
index 31f07d3..f5a5da0 100644
--- a/java/app.go
+++ b/java/app.go
@@ -751,14 +751,18 @@
// A prebuilt apk to import
Apk *string
- // The name of a certificate in the default certificate directory, blank to use the default
- // product certificate, or an android_app_certificate module name in the form ":module".
+ // The name of a certificate in the default certificate directory or an android_app_certificate
+ // module name in the form ":module". Should be empty if presigned or default_dev_cert is set.
Certificate *string
// Set this flag to true if the prebuilt apk is already signed. The certificate property must not
// be set for presigned modules.
Presigned *bool
+ // Sign with the default system dev certificate. Must be used judiciously. Most imported apps
+ // need to either specify a specific certificate or be presigned.
+ Default_dev_cert *bool
+
// Specifies that this app should be installed to the priv-app directory,
// where the system will grant it additional privileges not available to
// normal apps.
@@ -862,11 +866,18 @@
}
func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- if String(a.properties.Certificate) == "" && !Bool(a.properties.Presigned) {
- ctx.PropertyErrorf("certificate", "No certificate specified for prebuilt")
+ numCertPropsSet := 0
+ if String(a.properties.Certificate) != "" {
+ numCertPropsSet++
}
- if String(a.properties.Certificate) != "" && Bool(a.properties.Presigned) {
- ctx.PropertyErrorf("certificate", "Certificate can't be specified for presigned modules")
+ if Bool(a.properties.Presigned) {
+ numCertPropsSet++
+ }
+ if Bool(a.properties.Default_dev_cert) {
+ numCertPropsSet++
+ }
+ if numCertPropsSet != 1 {
+ ctx.ModuleErrorf("One and only one of certficate, presigned, and default_dev_cert properties must be set")
}
_, certificates := collectAppDeps(ctx)
@@ -907,7 +918,9 @@
// Sign or align the package
// TODO: Handle EXTERNAL
if !Bool(a.properties.Presigned) {
- certificates = processMainCert(a.ModuleBase, *a.properties.Certificate, certificates, ctx)
+ // If the certificate property is empty at this point, default_dev_cert must be set to true.
+ // Which makes processMainCert's behavior for the empty cert string WAI.
+ certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
if len(certificates) != 1 {
ctx.ModuleErrorf("Unexpected number of certificates were extracted: %q", certificates)
}
diff --git a/java/app_test.go b/java/app_test.go
index 564211c..be1ff29 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1164,6 +1164,35 @@
}
}
+func TestAndroidAppImport_DefaultDevCert(t *testing.T) {
+ ctx, _ := testJava(t, `
+ android_app_import {
+ name: "foo",
+ apk: "prebuilts/apk/app.apk",
+ default_dev_cert: true,
+ dex_preopt: {
+ enabled: true,
+ },
+ }
+ `)
+
+ variant := ctx.ModuleForTests("foo", "android_common")
+
+ // Check dexpreopt outputs.
+ if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
+ variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
+ t.Errorf("can't find dexpreopt outputs")
+ }
+
+ // Check cert signing flag.
+ signedApk := variant.Output("signed/foo.apk")
+ signingFlag := signedApk.Args["certificates"]
+ expected := "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8"
+ if expected != signingFlag {
+ t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
+ }
+}
+
func TestAndroidAppImport_DpiVariants(t *testing.T) {
bp := `
android_app_import {
@@ -1177,7 +1206,7 @@
apk: "prebuilts/apk/app_xxhdpi.apk",
},
},
- certificate: "PRESIGNED",
+ presigned: true,
dex_preopt: {
enabled: true,
},
@@ -1307,7 +1336,7 @@
apk: "prebuilts/apk/app_arm64.apk",
},
},
- certificate: "PRESIGNED",
+ presigned: true,
dex_preopt: {
enabled: true,
},
@@ -1326,7 +1355,7 @@
apk: "prebuilts/apk/app_arm.apk",
},
},
- certificate: "PRESIGNED",
+ presigned: true,
dex_preopt: {
enabled: true,
},
diff --git a/java/droiddoc.go b/java/droiddoc.go
index b474948..aaba285 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -64,10 +64,7 @@
// the java library (in classpath) for documentation that provides java srcs and srcjars.
Srcs_lib *string
- // the base dirs under srcs_lib will be scanned for java srcs.
- Srcs_lib_whitelist_dirs []string
-
- // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
+ // List of packages to document from srcs_lib
Srcs_lib_whitelist_pkgs []string
// If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
@@ -428,19 +425,6 @@
}
}
-func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
- for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
- for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
- // convert foo.bar.baz to foo/bar/baz
- pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
- prefix := filepath.Join(dir, pkgAsPath)
- if _, found := whitelistPathPrefixes[prefix]; !found {
- whitelistPathPrefixes[prefix] = true
- }
- }
- }
-}
-
func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
var flags droiddocBuilderFlags
@@ -480,13 +464,12 @@
outSrcFiles := make(android.Paths, 0, len(srcFiles))
+ aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
+
for _, srcFile := range srcFiles {
switch srcFile.Ext() {
case ".aidl":
- javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps)
- outSrcFiles = append(outSrcFiles, javaFile)
- case ".sysprop":
- javaFile := genSysprop(ctx, srcFile)
+ javaFile := genAidl(ctx, srcFile, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
outSrcFiles = append(outSrcFiles, javaFile)
case ".logtags":
javaFile := genLogtags(ctx, srcFile)
@@ -537,14 +520,13 @@
switch dep := module.(type) {
case Dependency:
srcs := dep.(SrcDependency).CompiledSrcs()
- whitelistPathPrefixes := make(map[string]bool)
- j.genWhitelistPathPrefixes(whitelistPathPrefixes)
for _, src := range srcs {
if _, ok := src.(android.WritablePath); ok { // generated sources
deps.srcs = append(deps.srcs, src)
} else { // select source path for documentation based on whitelist path prefixs.
- for k := range whitelistPathPrefixes {
- if strings.HasPrefix(src.Rel(), k) {
+ for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
+ pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
+ if strings.HasPrefix(src.Rel(), pkgAsPath) {
deps.srcs = append(deps.srcs, src)
break
}
diff --git a/java/gen.go b/java/gen.go
index 69965ec..532a22c 100644
--- a/java/gen.go
+++ b/java/gen.go
@@ -53,22 +53,18 @@
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 {
javaFile := android.GenPathWithExt(ctx, "aidl", aidlFile, "java")
depFile := javaFile.String() + ".d"
- baseDir := strings.TrimSuffix(aidlFile.String(), aidlFile.Rel())
- if baseDir != "" {
- aidlFlags += " -I" + baseDir
- }
ctx.Build(pctx, android.BuildParams{
Rule: aidl,
@@ -98,7 +94,7 @@
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,20 +102,38 @@
Description: "sysprop_java " + syspropFile.Rel(),
Output: srcJarFile,
Input: syspropFile,
+ Args: map[string]string{
+ "scope": scope,
+ },
})
return srcJarFile
}
+func genAidlIncludeFlags(srcFiles android.Paths) string {
+ var baseDirs []string
+ for _, srcFile := range srcFiles {
+ if srcFile.Ext() == ".aidl" {
+ baseDir := strings.TrimSuffix(srcFile.String(), srcFile.Rel())
+ if baseDir != "" && !android.InList(baseDir, baseDirs) {
+ baseDirs = append(baseDirs, baseDir)
+ }
+ }
+ }
+ return android.JoinWithPrefix(baseDirs, " -I")
+}
+
func (j *Module) genSources(ctx android.ModuleContext, srcFiles android.Paths,
flags javaBuilderFlags) android.Paths {
outSrcFiles := make(android.Paths, 0, len(srcFiles))
+ aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
+
for _, srcFile := range srcFiles {
switch srcFile.Ext() {
case ".aidl":
- javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps)
+ javaFile := genAidl(ctx, srcFile, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
outSrcFiles = append(outSrcFiles, javaFile)
case ".logtags":
j.logtagsSrcs = append(j.logtagsSrcs, srcFile)
@@ -129,7 +143,27 @@
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 afb1218..2193a2b 100644
--- a/java/java.go
+++ b/java/java.go
@@ -183,6 +183,10 @@
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) 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/java/sdk_library.go b/java/sdk_library.go
index d38088d..56b30b2 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -103,11 +103,7 @@
// the java library (in classpath) for documentation that provides java srcs and srcjars.
Srcs_lib *string
- // the base dirs under srcs_lib will be scanned for java srcs.
- Srcs_lib_whitelist_dirs []string
-
- // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
- // Defaults to "android.annotation".
+ // list of packages to document from srcs_lib. Defaults to "android.annotation".
Srcs_lib_whitelist_pkgs []string
// a list of top-level directories containing files to merge qualifier annotations
@@ -443,7 +439,6 @@
Srcs []string
Installable *bool
Srcs_lib *string
- Srcs_lib_whitelist_dirs []string
Srcs_lib_whitelist_pkgs []string
Sdk_version *string
Libs []string
@@ -535,7 +530,6 @@
module.latestRemovedApiFilegroupName(apiScope))
props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true)
props.Srcs_lib = module.sdkLibraryProperties.Srcs_lib
- props.Srcs_lib_whitelist_dirs = module.sdkLibraryProperties.Srcs_lib_whitelist_dirs
props.Srcs_lib_whitelist_pkgs = module.sdkLibraryProperties.Srcs_lib_whitelist_pkgs
mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
@@ -550,9 +544,9 @@
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.
diff --git a/scripts/freeze-sysprop-api-files.sh b/scripts/freeze-sysprop-api-files.sh
new file mode 100755
index 0000000..1b2ff7c
--- /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 <modulePath> <moduleName>
+#
+# <modulePath>: the directory, either relative or absolute, which holds the
+# Android.bp file defining sysprop_library.
+#
+# <moduleName>: 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 <modulePath> <moduleName>" >&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 0000000..a4cb506
--- /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 <modulePath> <moduleName>" >&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 86061c6..c7669bd 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 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 @@
// 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 @@
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 @@
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 @@
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 0566036..5345770 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -57,16 +57,11 @@
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 @@
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 @@
"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 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 @@
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 @@
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)
}
diff --git a/ui/build/cleanbuild.go b/ui/build/cleanbuild.go
index 8e7f96a..bfe2c36 100644
--- a/ui/build/cleanbuild.go
+++ b/ui/build/cleanbuild.go
@@ -99,6 +99,7 @@
productOut("*.img"),
productOut("*.zip"),
productOut("android-info.txt"),
+ productOut("apex"),
productOut("kernel"),
productOut("data"),
productOut("skin"),