summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android/mutator.go2
-rw-r--r--android/neverallow.go18
-rw-r--r--android/neverallow_test.go4
-rw-r--r--cc/androidmk.go4
-rw-r--r--cc/cc.go9
-rw-r--r--cc/config/arm64_device.go2
-rw-r--r--cc/config/clang.go2
-rw-r--r--cc/installer.go4
-rw-r--r--cc/library.go12
-rw-r--r--cc/prebuilt.go5
-rwxr-xr-xjava/app.go18
-rw-r--r--java/app_test.go102
-rw-r--r--java/java.go26
-rw-r--r--java/sdk.go21
14 files changed, 200 insertions, 29 deletions
diff --git a/android/mutator.go b/android/mutator.go
index a46d4beb1..10a815ae4 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -103,7 +103,7 @@ var postDeps = []RegisterMutatorFunc{
registerPathDepsMutator,
RegisterPrebuiltsPostDepsMutators,
RegisterVisibilityRuleEnforcer,
- registerNeverallowMutator,
+ RegisterNeverallowMutator,
RegisterOverridePostDepsMutators,
}
diff --git a/android/neverallow.go b/android/neverallow.go
index 04ec27d20..cf09792e0 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -42,7 +42,7 @@ import (
// counts as a match
// - it has none of the "Without" properties matched (same rules as above)
-func registerNeverallowMutator(ctx RegisterMutatorsContext) {
+func RegisterNeverallowMutator(ctx RegisterMutatorsContext) {
ctx.BottomUp("neverallow", neverallowMutator).Parallel()
}
@@ -247,7 +247,7 @@ func neverallowMutator(ctx BottomUpMutatorContext) {
}
type ValueMatcher interface {
- test(string) bool
+ Test(string) bool
String() string
}
@@ -255,7 +255,7 @@ type equalMatcher struct {
expected string
}
-func (m *equalMatcher) test(value string) bool {
+func (m *equalMatcher) Test(value string) bool {
return m.expected == value
}
@@ -266,7 +266,7 @@ func (m *equalMatcher) String() string {
type anyMatcher struct {
}
-func (m *anyMatcher) test(value string) bool {
+func (m *anyMatcher) Test(value string) bool {
return true
}
@@ -280,7 +280,7 @@ type startsWithMatcher struct {
prefix string
}
-func (m *startsWithMatcher) test(value string) bool {
+func (m *startsWithMatcher) Test(value string) bool {
return strings.HasPrefix(value, m.prefix)
}
@@ -292,7 +292,7 @@ type regexMatcher struct {
re *regexp.Regexp
}
-func (m *regexMatcher) test(value string) bool {
+func (m *regexMatcher) Test(value string) bool {
return m.re.MatchString(value)
}
@@ -302,7 +302,7 @@ func (m *regexMatcher) String() string {
type isSetMatcher struct{}
-func (m *isSetMatcher) test(value string) bool {
+func (m *isSetMatcher) Test(value string) bool {
return value != ""
}
@@ -573,7 +573,7 @@ func hasProperty(properties []interface{}, prop ruleProperty) bool {
}
check := func(value string) bool {
- return prop.matcher.test(value)
+ return prop.matcher.Test(value)
}
if matchValue(propertiesValue, check) {
@@ -630,6 +630,6 @@ func neverallowRules(config Config) []Rule {
// Overrides the default neverallow rules for the supplied config.
//
// For testing only.
-func setTestNeverallowRules(config Config, testRules []Rule) {
+func SetTestNeverallowRules(config Config, testRules []Rule) {
config.Once(neverallowRulesKey, func() interface{} { return testRules })
}
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index 0373b7923..2fc42e31f 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -313,7 +313,7 @@ func TestNeverallow(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
// If the test has its own rules then use them instead of the default ones.
if test.rules != nil {
- setTestNeverallowRules(config, test.rules)
+ SetTestNeverallowRules(config, test.rules)
}
_, errs := testNeverallow(config)
CheckErrorsAgainstExpectations(t, errs, test.expectedErrors)
@@ -327,7 +327,7 @@ func testNeverallow(config Config) (*TestContext, []error) {
ctx.RegisterModuleType("java_library", newMockJavaLibraryModule)
ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
- ctx.PostDepsMutators(registerNeverallowMutator)
+ ctx.PostDepsMutators(RegisterNeverallowMutator)
ctx.Register(config)
_, errs := ctx.ParseBlueprintsFiles("Android.bp")
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 19c71826f..5438b149d 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -271,6 +271,10 @@ func (library *libraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries
entries.SubName = "." + library.stubsVersion()
}
entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+ // Note library.skipInstall() has a special case to get here for static
+ // libraries that otherwise would have skipped installation and hence not
+ // have executed AndroidMkEntries at all. The reason is to ensure they get
+ // a NOTICE file make target which other libraries might depend on.
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
if library.buildStubs() {
entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
diff --git a/cc/cc.go b/cc/cc.go
index 8c21941e5..02014049b 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -404,6 +404,7 @@ type installer interface {
inSanitizerDir() bool
hostToolPath() android.OptionalPath
relativeInstallPath() string
+ skipInstall(mod *Module)
}
type xref interface {
@@ -2639,6 +2640,14 @@ func (c *Module) InstallInRecovery() bool {
return c.InRecovery()
}
+func (c *Module) SkipInstall() {
+ if c.installer == nil {
+ c.ModuleBase.SkipInstall()
+ return
+ }
+ c.installer.skipInstall(c)
+}
+
func (c *Module) HostToolPath() android.OptionalPath {
if c.installer == nil {
return android.OptionalPath{}
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index 19aedd99d..5575baaab 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -37,10 +37,8 @@ var (
}
arm64Ldflags = []string{
- "-Wl,-m,aarch64_elf64_le_vec",
"-Wl,--hash-style=gnu",
"-Wl,-z,separate-code",
- "-fuse-ld=gold",
"-Wl,--icf=safe",
}
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 274ccd5d5..bdd9030f4 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -80,10 +80,8 @@ var ClangUnknownCflags = sorted([]string{
// Ldflags that should be filtered out when linking with clang lld
var ClangUnknownLldflags = sorted([]string{
- "-fuse-ld=gold",
"-Wl,--fix-cortex-a8",
"-Wl,--no-fix-cortex-a8",
- "-Wl,-m,aarch64_elf64_le_vec",
})
var ClangLibToolingUnknownCflags = sorted([]string{})
diff --git a/cc/installer.go b/cc/installer.go
index 200d59e9f..0b4a68cc8 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -106,3 +106,7 @@ func (installer *baseInstaller) hostToolPath() android.OptionalPath {
func (installer *baseInstaller) relativeInstallPath() string {
return String(installer.Properties.Relative_install_path)
}
+
+func (installer *baseInstaller) skipInstall(mod *Module) {
+ mod.ModuleBase.SkipInstall()
+}
diff --git a/cc/library.go b/cc/library.go
index 140f87a0a..94fffb951 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1329,6 +1329,18 @@ func (library *libraryDecorator) availableFor(what string) bool {
return android.CheckAvailableForApex(what, list)
}
+func (library *libraryDecorator) skipInstall(mod *Module) {
+ if library.static() && library.buildStatic() && !library.buildStubs() {
+ // If we're asked to skip installation of a static library (in particular
+ // when it's not //apex_available:platform) we still want an AndroidMk entry
+ // for it to ensure we get the relevant NOTICE file targets (cf.
+ // notice_files.mk) that other libraries might depend on. AndroidMkEntries
+ // always sets LOCAL_UNINSTALLABLE_MODULE for these entries.
+ return
+ }
+ mod.ModuleBase.SkipInstall()
+}
+
var versioningMacroNamesListKey = android.NewOnceKey("versioningMacroNamesList")
func versioningMacroNamesList(config android.Config) *map[string]string {
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index fc9cc17d3..2ef31950e 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -155,6 +155,10 @@ func (p *prebuiltLibraryLinker) disablePrebuilt() {
p.properties.Srcs = nil
}
+func (p *prebuiltLibraryLinker) skipInstall(mod *Module) {
+ mod.ModuleBase.SkipInstall()
+}
+
func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
module, library := NewLibrary(hod)
module.compiler = nil
@@ -163,6 +167,7 @@ func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDec
libraryDecorator: library,
}
module.linker = prebuilt
+ module.installer = prebuilt
module.AddProperties(&prebuilt.properties)
diff --git a/java/app.go b/java/app.go
index ae9cd5f11..ac5121a3d 100755
--- a/java/app.go
+++ b/java/app.go
@@ -110,6 +110,10 @@ type appProperties struct {
PreventInstall bool `blueprint:"mutated"`
HideFromMake bool `blueprint:"mutated"`
IsCoverageVariant bool `blueprint:"mutated"`
+
+ // Whether this app is considered mainline updatable or not. When set to true, this will enforce
+ // additional rules for making sure that the APK is truly updatable. Default is false.
+ Updatable *bool
}
// android_app properties that can be overridden by override_android_app
@@ -249,11 +253,21 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon
}
func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- a.checkPlatformAPI(ctx)
- a.checkSdkVersion(ctx)
+ a.checkAppSdkVersions(ctx)
a.generateAndroidBuildActions(ctx)
}
+func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
+ if Bool(a.appProperties.Updatable) {
+ if !a.sdkVersion().stable() {
+ ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.sdkVersion())
+ }
+ }
+
+ a.checkPlatformAPI(ctx)
+ a.checkSdkVersions(ctx)
+}
+
// Returns true if the native libraries should be stored in the APK uncompressed and the
// extractNativeLibs application flag should be set to false in the manifest.
func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
diff --git a/java/app_test.go b/java/app_test.go
index 43696dbb8..7b04e4629 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -264,6 +264,108 @@ func TestAndroidAppLinkType(t *testing.T) {
`)
}
+func TestUpdatableApps(t *testing.T) {
+ testCases := []struct {
+ name string
+ bp string
+ expectedError string
+ }{
+ {
+ name: "Stable public SDK",
+ bp: `android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "29",
+ updatable: true,
+ }`,
+ },
+ {
+ name: "Stable system SDK",
+ bp: `android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "system_29",
+ updatable: true,
+ }`,
+ },
+ {
+ name: "Current public SDK",
+ bp: `android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ updatable: true,
+ }`,
+ },
+ {
+ name: "Current system SDK",
+ bp: `android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "system_current",
+ updatable: true,
+ }`,
+ },
+ {
+ name: "Current module SDK",
+ bp: `android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "module_current",
+ updatable: true,
+ }`,
+ },
+ {
+ name: "Current core SDK",
+ bp: `android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "core_current",
+ updatable: true,
+ }`,
+ },
+ {
+ name: "No Platform APIs",
+ bp: `android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ platform_apis: true,
+ updatable: true,
+ }`,
+ expectedError: "Updatable apps must use stable SDKs",
+ },
+ {
+ name: "No Core Platform APIs",
+ bp: `android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "core_platform",
+ updatable: true,
+ }`,
+ expectedError: "Updatable apps must use stable SDKs",
+ },
+ {
+ name: "No unspecified APIs",
+ bp: `android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ updatable: true,
+ }`,
+ expectedError: "Updatable apps must use stable SDK",
+ },
+ }
+
+ for _, test := range testCases {
+ t.Run(test.name, func(t *testing.T) {
+ if test.expectedError == "" {
+ testJava(t, test.bp)
+ } else {
+ testJavaError(t, test.expectedError, test.bp)
+ }
+ })
+ }
+}
+
func TestResourceDirs(t *testing.T) {
testCases := []struct {
name string
diff --git a/java/java.go b/java/java.go
index a8ca3ffef..61974f5af 100644
--- a/java/java.go
+++ b/java/java.go
@@ -86,7 +86,7 @@ func RegisterJavaBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
}
-func (j *Module) checkSdkVersion(ctx android.ModuleContext) {
+func (j *Module) checkSdkVersions(ctx android.ModuleContext) {
if j.SocSpecific() || j.DeviceSpecific() ||
(j.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
if sc, ok := ctx.Module().(sdkContext); ok {
@@ -96,6 +96,18 @@ func (j *Module) checkSdkVersion(ctx android.ModuleContext) {
}
}
}
+
+ ctx.VisitDirectDeps(func(module android.Module) {
+ tag := ctx.OtherModuleDependencyTag(module)
+ switch module.(type) {
+ // TODO(satayev): cover other types as well, e.g. imports
+ case *Library, *AndroidLibrary:
+ switch tag {
+ case bootClasspathTag, libTag, staticLibTag, java9LibTag:
+ checkLinkType(ctx, j, module.(linkTypeContext), tag.(dependencyTag))
+ }
+ }
+ })
}
func (j *Module) checkPlatformAPI(ctx android.ModuleContext) {
@@ -898,15 +910,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
// Handled by AndroidApp.collectAppDeps
return
}
- switch module.(type) {
- case *Library, *AndroidLibrary:
- if to, ok := module.(linkTypeContext); ok {
- switch tag {
- case bootClasspathTag, libTag, staticLibTag:
- checkLinkType(ctx, j, to, tag.(dependencyTag))
- }
- }
- }
+
switch dep := module.(type) {
case SdkLibraryDependency:
switch tag {
@@ -1818,7 +1822,7 @@ func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bo
}
func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- j.checkSdkVersion(ctx)
+ j.checkSdkVersions(ctx)
j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
diff --git a/java/sdk.go b/java/sdk.go
index 0e132d399..92076f4b5 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -147,6 +147,10 @@ type sdkSpec struct {
raw string
}
+func (s sdkSpec) String() string {
+ return fmt.Sprintf("%s_%s", s.kind, s.version)
+}
+
// valid checks if this sdkSpec is well-formed. Note however that true doesn't mean that the
// specified SDK actually exists.
func (s sdkSpec) valid() bool {
@@ -158,6 +162,23 @@ func (s sdkSpec) specified() bool {
return s.valid() && s.kind != sdkPrivate
}
+// whether the API surface is managed and versioned, i.e. has .txt file that
+// get frozen on SDK freeze and changes get reviewed by API council.
+func (s sdkSpec) stable() bool {
+ if !s.specified() {
+ return false
+ }
+ switch s.kind {
+ case sdkCore, sdkPublic, sdkSystem, sdkModule, sdkSystemServer:
+ return true
+ case sdkNone, sdkCorePlatform, sdkTest, sdkPrivate:
+ return false
+ default:
+ panic(fmt.Errorf("unknown sdkKind=%v", s.kind))
+ }
+ return false
+}
+
// prebuiltSdkAvailableForUnbundledBuilt tells whether this sdkSpec can have a prebuilt SDK
// that can be used for unbundled builds.
func (s sdkSpec) prebuiltSdkAvailableForUnbundledBuild() bool {