Merge changes I4ab7e1a3,Ib525b2f5,I2d4c54fb into rvc-dev

* changes:
  Generate combined deps-info for all updatable modules.
  Remove ApexBundleDepsInfo.MinSdkVersion()
  Add "updatable" property to ApexModule interface.
This commit is contained in:
Artur Satayev 2020-05-27 20:58:27 +00:00 committed by Android (Google) Code Review
commit 07d215215b
7 changed files with 148 additions and 28 deletions

View File

@ -489,6 +489,7 @@ bootstrap_go_package {
srcs: [ srcs: [
"apex/androidmk.go", "apex/androidmk.go",
"apex/apex.go", "apex/apex.go",
"apex/apex_singleton.go",
"apex/builder.go", "apex/builder.go",
"apex/key.go", "apex/key.go",
"apex/prebuilt.go", "apex/prebuilt.go",

View File

@ -33,6 +33,7 @@ type ApexInfo struct {
ApexName string ApexName string
MinSdkVersion int MinSdkVersion int
Updatable bool
} }
// Extracted from ApexModule to make it easier to define custom subsets of the // Extracted from ApexModule to make it easier to define custom subsets of the
@ -116,6 +117,9 @@ type ApexModule interface {
// it returns 9 as string // it returns 9 as string
ChooseSdkVersion(versionList []string, maxSdkVersion int) (string, error) ChooseSdkVersion(versionList []string, maxSdkVersion int) (string, error)
// Tests if the module comes from an updatable APEX.
Updatable() bool
// List of APEXes that this module tests. The module has access to // List of APEXes that this module tests. The module has access to
// the private part of the listed APEXes even when it is not included in the // the private part of the listed APEXes even when it is not included in the
// APEXes. // APEXes.
@ -260,6 +264,10 @@ func (m *ApexModuleBase) checkApexAvailableProperty(mctx BaseModuleContext) {
} }
} }
func (m *ApexModuleBase) Updatable() bool {
return m.ApexProperties.Info.Updatable
}
type byApexName []ApexInfo type byApexName []ApexInfo
func (a byApexName) Len() int { return len(a) } func (a byApexName) Len() int { return len(a) }
@ -413,21 +421,16 @@ type ApexModuleDepInfo struct {
type DepNameToDepInfoMap map[string]ApexModuleDepInfo type DepNameToDepInfoMap map[string]ApexModuleDepInfo
type ApexBundleDepsInfo struct { type ApexBundleDepsInfo struct {
minSdkVersion string flatListPath OutputPath
flatListPath OutputPath fullListPath OutputPath
fullListPath OutputPath
} }
type ApexDepsInfoIntf interface { type ApexBundleDepsInfoIntf interface {
MinSdkVersion() string Updatable() bool
FlatListPath() Path FlatListPath() Path
FullListPath() Path FullListPath() Path
} }
func (d *ApexBundleDepsInfo) MinSdkVersion() string {
return d.minSdkVersion
}
func (d *ApexBundleDepsInfo) FlatListPath() Path { func (d *ApexBundleDepsInfo) FlatListPath() Path {
return d.flatListPath return d.flatListPath
} }
@ -436,14 +439,10 @@ func (d *ApexBundleDepsInfo) FullListPath() Path {
return d.fullListPath return d.fullListPath
} }
var _ ApexDepsInfoIntf = (*ApexBundleDepsInfo)(nil)
// Generate two module out files: // Generate two module out files:
// 1. FullList with transitive deps and their parents in the dep graph // 1. FullList with transitive deps and their parents in the dep graph
// 2. FlatList with a flat list of transitive deps // 2. FlatList with a flat list of transitive deps
func (d *ApexBundleDepsInfo) BuildDepsInfoLists(ctx ModuleContext, minSdkVersion string, depInfos DepNameToDepInfoMap) { func (d *ApexBundleDepsInfo) BuildDepsInfoLists(ctx ModuleContext, minSdkVersion string, depInfos DepNameToDepInfoMap) {
d.minSdkVersion = minSdkVersion
var fullContent strings.Builder var fullContent strings.Builder
var flatContent strings.Builder var flatContent strings.Builder

View File

@ -785,6 +785,7 @@ func apexDepsMutator(mctx android.TopDownMutatorContext) {
apexBundles = []android.ApexInfo{{ apexBundles = []android.ApexInfo{{
ApexName: mctx.ModuleName(), ApexName: mctx.ModuleName(),
MinSdkVersion: a.minSdkVersion(mctx), MinSdkVersion: a.minSdkVersion(mctx),
Updatable: a.Updatable(),
}} }}
directDep = true directDep = true
} else if am, ok := mctx.Module().(android.ApexModule); ok { } else if am, ok := mctx.Module().(android.ApexModule); ok {
@ -1828,6 +1829,12 @@ func PrettyPrintTag(tag blueprint.DependencyTag) string {
return tagString return tagString
} }
func (a *apexBundle) Updatable() bool {
return proptools.Bool(a.properties.Updatable)
}
var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil)
// Ensures that the dependencies are marked as available for this APEX // Ensures that the dependencies are marked as available for this APEX
func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) { func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
// Let's be practical. Availability for test, host, and the VNDK apex isn't important // Let's be practical. Availability for test, host, and the VNDK apex isn't important
@ -1876,7 +1883,7 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
} }
func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) { func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
if proptools.Bool(a.properties.Updatable) { if a.Updatable() {
if String(a.properties.Min_sdk_version) == "" { if String(a.properties.Min_sdk_version) == "" {
ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well") ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
} }
@ -2203,7 +2210,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// We don't need the optimization for updatable APEXes, as it might give false signal // We don't need the optimization for updatable APEXes, as it might give false signal
// to the system health when the APEXes are still bundled (b/149805758) // to the system health when the APEXes are still bundled (b/149805758)
if proptools.Bool(a.properties.Updatable) && a.properties.ApexType == imageApex { if a.Updatable() && a.properties.ApexType == imageApex {
a.linkToSystemLib = false a.linkToSystemLib = false
} }

65
apex/apex_singleton.go Normal file
View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2020 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.
*/
package apex
import (
"github.com/google/blueprint"
"android/soong/android"
)
func init() {
android.RegisterSingletonType("apex_depsinfo_singleton", apexDepsInfoSingletonFactory)
}
type apexDepsInfoSingleton struct {
// Output file with all flatlists from updatable modules' deps-info combined
updatableFlatListsPath android.OutputPath
}
func apexDepsInfoSingletonFactory() android.Singleton {
return &apexDepsInfoSingleton{}
}
var combineFilesRule = pctx.AndroidStaticRule("combineFilesRule",
blueprint.RuleParams{
Command: "cat $out.rsp | xargs cat > $out",
Rspfile: "$out.rsp",
RspfileContent: "$in",
},
)
func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContext) {
updatableFlatLists := android.Paths{}
ctx.VisitAllModules(func(module android.Module) {
if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok {
if path := binaryInfo.FlatListPath(); path != nil {
if binaryInfo.Updatable() {
updatableFlatLists = append(updatableFlatLists, path)
}
}
}
})
s.updatableFlatListsPath = android.PathForOutput(ctx, "apex", "depsinfo", "updatable-flatlists.txt")
ctx.Build(pctx, android.BuildParams{
Rule: combineFilesRule,
Description: "Generate " + s.updatableFlatListsPath.String(),
Inputs: updatableFlatLists,
Output: s.updatableFlatListsPath,
})
}

View File

@ -4437,6 +4437,13 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg, bp string, transformDe
"system/sepolicy/apex/some-updatable-apex-file_contexts", "system/sepolicy/apex/some-updatable-apex-file_contexts",
], ],
} }
filegroup {
name: "some-non-updatable-apex-file_contexts",
srcs: [
"system/sepolicy/apex/some-non-updatable-apex-file_contexts",
],
}
` `
bp += cc.GatherRequiredDepsForTest(android.Android) bp += cc.GatherRequiredDepsForTest(android.Android)
bp += java.GatherRequiredDepsForTest() bp += java.GatherRequiredDepsForTest()
@ -4449,6 +4456,7 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg, bp string, transformDe
"apex_manifest.json": nil, "apex_manifest.json": nil,
"AndroidManifest.xml": nil, "AndroidManifest.xml": nil,
"system/sepolicy/apex/some-updatable-apex-file_contexts": nil, "system/sepolicy/apex/some-updatable-apex-file_contexts": nil,
"system/sepolicy/apex/some-non-updatable-apex-file_contexts": nil,
"system/sepolicy/apex/com.android.art.something-file_contexts": nil, "system/sepolicy/apex/com.android.art.something-file_contexts": nil,
"framework/aidl/a.aidl": nil, "framework/aidl/a.aidl": nil,
} }
@ -4519,6 +4527,14 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
], ],
} }
java_library {
name: "some-non-updatable-apex-lib",
srcs: ["a.java"],
apex_available: [
"some-non-updatable-apex",
],
}
java_library { java_library {
name: "some-platform-lib", name: "some-platform-lib",
srcs: ["a.java"], srcs: ["a.java"],
@ -4540,16 +4556,30 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
name: "some-updatable-apex", name: "some-updatable-apex",
key: "some-updatable-apex.key", key: "some-updatable-apex.key",
java_libs: ["some-updatable-apex-lib"], java_libs: ["some-updatable-apex-lib"],
updatable: true,
min_sdk_version: "current",
}
apex {
name: "some-non-updatable-apex",
key: "some-non-updatable-apex.key",
java_libs: ["some-non-updatable-apex-lib"],
} }
apex_key { apex_key {
name: "some-updatable-apex.key", name: "some-updatable-apex.key",
} }
apex_key {
name: "some-non-updatable-apex.key",
}
apex { apex {
name: "com.android.art.something", name: "com.android.art.something",
key: "com.android.art.something.key", key: "com.android.art.something.key",
java_libs: ["some-art-lib"], java_libs: ["some-art-lib"],
updatable: true,
min_sdk_version: "current",
} }
apex_key { apex_key {
@ -4580,6 +4610,13 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
} }
testNoUpdatableJarsInBootImage(t, error, bp, transform) testNoUpdatableJarsInBootImage(t, error, bp, transform)
// non-updatable jar from some other apex in the ART boot image => error
error = "module 'some-non-updatable-apex-lib' is not allowed in the ART boot image"
transform = func(config *dexpreopt.GlobalConfig) {
config.ArtApexJars = []string{"some-non-updatable-apex-lib"}
}
testNoUpdatableJarsInBootImage(t, error, bp, transform)
// updatable jar from some other apex in the framework boot image => error // updatable jar from some other apex in the framework boot image => error
error = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the framework boot image" error = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the framework boot image"
transform = func(config *dexpreopt.GlobalConfig) { transform = func(config *dexpreopt.GlobalConfig) {
@ -4587,6 +4624,12 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
} }
testNoUpdatableJarsInBootImage(t, error, bp, transform) testNoUpdatableJarsInBootImage(t, error, bp, transform)
// non-updatable jar from some other apex in the framework boot image => ok
transform = func(config *dexpreopt.GlobalConfig) {
config.BootJars = []string{"some-non-updatable-apex-lib"}
}
testNoUpdatableJarsInBootImage(t, "", bp, transform)
// nonexistent jar in the ART boot image => error // nonexistent jar in the ART boot image => error
error = "failed to find a dex jar path for module 'nonexistent'" error = "failed to find a dex jar path for module 'nonexistent'"
transform = func(config *dexpreopt.GlobalConfig) { transform = func(config *dexpreopt.GlobalConfig) {
@ -4602,7 +4645,7 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
testNoUpdatableJarsInBootImage(t, error, bp, transform) testNoUpdatableJarsInBootImage(t, error, bp, transform)
// platform jar in the ART boot image => error // platform jar in the ART boot image => error
error = "module 'some-platform-lib' is part of the platform and not allowed in the ART boot image" error = "module 'some-platform-lib' is not allowed in the ART boot image"
transform = func(config *dexpreopt.GlobalConfig) { transform = func(config *dexpreopt.GlobalConfig) {
config.ArtApexJars = []string{"some-platform-lib"} config.ArtApexJars = []string{"some-platform-lib"}
} }

View File

@ -414,7 +414,7 @@ func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
} }
func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) { func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
if Bool(a.appProperties.Updatable) { if a.Updatable() {
if !a.sdkVersion().stable() { if !a.sdkVersion().stable() {
ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.sdkVersion()) ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.sdkVersion())
} }
@ -880,6 +880,10 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(), depsInfo) a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(), depsInfo)
} }
func (a *AndroidApp) Updatable() bool {
return Bool(a.appProperties.Updatable) || a.ApexModuleBase.Updatable()
}
func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string { func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName()) certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
if overridden { if overridden {

View File

@ -264,27 +264,28 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul
// Check that this module satisfies constraints for a particular boot image. // Check that this module satisfies constraints for a particular boot image.
apex, isApexModule := module.(android.ApexModule) apex, isApexModule := module.(android.ApexModule)
fromUpdatableApex := isApexModule && apex.Updatable()
if image.name == artBootImageName { if image.name == artBootImageName {
if isApexModule && strings.HasPrefix(apex.ApexName(), "com.android.art.") { if isApexModule && strings.HasPrefix(apex.ApexName(), "com.android.art.") {
// ok, found the jar in the ART apex // ok: found the jar in the ART apex
} else if isApexModule && !apex.IsForPlatform() {
// this jar is part of an updatable apex other than ART, fail immediately
ctx.Errorf("module '%s' from updatable apex '%s' is not allowed in the ART boot image", name, apex.ApexName())
} else if isApexModule && apex.IsForPlatform() && Bool(module.(*Library).deviceProperties.Hostdex) { } else if isApexModule && apex.IsForPlatform() && Bool(module.(*Library).deviceProperties.Hostdex) {
// this is a special "hostdex" variant, skip it and resume search // exception (skip and continue): special "hostdex" platform variant
return -1, nil return -1, nil
} else if name == "jacocoagent" && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { } else if name == "jacocoagent" && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
// this is Jacoco platform variant for a coverage build, skip it and resume search // exception (skip and continue): Jacoco platform variant for a coverage build
return -1, nil return -1, nil
} else if fromUpdatableApex {
// error: this jar is part of an updatable apex other than ART
ctx.Errorf("module '%s' from updatable apex '%s' is not allowed in the ART boot image", name, apex.ApexName())
} else { } else {
// this (installable) jar is part of the platform, fail immediately // error: this jar is part of the platform or a non-updatable apex
ctx.Errorf("module '%s' is part of the platform and not allowed in the ART boot image", name) ctx.Errorf("module '%s' is not allowed in the ART boot image", name)
} }
} else if image.name == frameworkBootImageName { } else if image.name == frameworkBootImageName {
if !isApexModule || apex.IsForPlatform() { if !fromUpdatableApex {
// ok, this jar is part of the platform // ok: this jar is part of the platform or a non-updatable apex
} else { } else {
// this jar is part of an updatable apex, fail immediately // error: this jar is part of an updatable apex
ctx.Errorf("module '%s' from updatable apex '%s' is not allowed in the framework boot image", name, apex.ApexName()) ctx.Errorf("module '%s' from updatable apex '%s' is not allowed in the framework boot image", name, apex.ApexName())
} }
} else { } else {