Merge "apex: file_contexts for override_apex flattened" into rvc-dev
diff --git a/android/androidmk.go b/android/androidmk.go
index c296a5b..6ba68af 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -198,6 +198,10 @@
a.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
+ if am, ok := mod.(ApexModule); ok {
+ a.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
+ }
+
archStr := amod.Arch().ArchType.String()
host := false
switch amod.Os().Class {
diff --git a/android/apex.go b/android/apex.go
index 9bf6fc7..1a43ce4 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -100,6 +100,16 @@
// Tests if this module is available for the specified APEX or ":platform"
AvailableFor(what string) bool
+ // Return true if this module is not available to platform (i.e. apex_available
+ // property doesn't have "//apex_available:platform"), or shouldn't be available
+ // to platform, which is the case when this module depends on other module that
+ // isn't available to platform.
+ NotAvailableForPlatform() bool
+
+ // Mark that this module is not available to platform. Set by the
+ // check-platform-availability mutator in the apex package.
+ SetNotAvailableForPlatform()
+
// Returns the highest version which is <= maxSdkVersion.
// For example, with maxSdkVersion is 10 and versionList is [9,11]
// it returns 9 as string
@@ -117,6 +127,8 @@
Apex_available []string
Info ApexInfo `blueprint:"mutated"`
+
+ NotAvailableForPlatform bool `blueprint:"mutated"`
}
// Marker interface that identifies dependencies that are excluded from APEX
@@ -201,6 +213,14 @@
return CheckAvailableForApex(what, m.ApexProperties.Apex_available)
}
+func (m *ApexModuleBase) NotAvailableForPlatform() bool {
+ return m.ApexProperties.NotAvailableForPlatform
+}
+
+func (m *ApexModuleBase) SetNotAvailableForPlatform() {
+ m.ApexProperties.NotAvailableForPlatform = true
+}
+
func (m *ApexModuleBase) DepIsInSameApex(ctx BaseModuleContext, dep Module) bool {
// By default, if there is a dependency from A to B, we try to include both in the same APEX,
// unless B is explicitly from outside of the APEX (i.e. a stubs lib). Thus, returning true.
diff --git a/apex/apex.go b/apex/apex.go
index 82e2442..ec87f5b 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -561,7 +561,6 @@
"libnativebridge_lazy",
"libnativeloader_lazy",
"libnativewindow_headers",
- "libopus",
"libpdx_headers",
"libprocessgroup",
"libprocessgroup_headers",
@@ -833,6 +832,7 @@
ctx.BottomUp("apex", apexMutator).Parallel()
ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
ctx.BottomUp("apex_uses", apexUsesMutator).Parallel()
+ ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
}
// Mark the direct and transitive dependencies of apex bundles so that they
@@ -870,6 +870,60 @@
})
}
+// mark if a module cannot be available to platform. A module cannot be available
+// to platform if 1) it is explicitly marked as not available (i.e. "//apex_available:platform"
+// is absent) or 2) it depends on another module that isn't (or can't be) available to platform
+func markPlatformAvailability(mctx android.BottomUpMutatorContext) {
+ // Host and recovery are not considered as platform
+ if mctx.Host() || mctx.Module().InstallInRecovery() {
+ return
+ }
+
+ if am, ok := mctx.Module().(android.ApexModule); ok {
+ availableToPlatform := am.AvailableFor(android.AvailableToPlatform)
+
+ // In a rare case when a lib is marked as available only to an apex
+ // but the apex doesn't exist. This can happen in a partial manifest branch
+ // like master-art. Currently, libstatssocket in the stats APEX is causing
+ // this problem.
+ // Include the lib in platform because the module SDK that ought to provide
+ // it doesn't exist, so it would otherwise be left out completely.
+ // TODO(b/154888298) remove this by adding those libraries in module SDKS and skipping
+ // this check for libraries provided by SDKs.
+ if !availableToPlatform && !android.InAnyApex(am.Name()) {
+ availableToPlatform = true
+ }
+
+ // If any of the dep is not available to platform, this module is also considered
+ // as being not available to platform even if it has "//apex_available:platform"
+ mctx.VisitDirectDeps(func(child android.Module) {
+ if !am.DepIsInSameApex(mctx, child) {
+ // if the dependency crosses apex boundary, don't consider it
+ return
+ }
+ if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() {
+ availableToPlatform = false
+ // TODO(b/154889534) trigger an error when 'am' has "//apex_available:platform"
+ }
+ })
+
+ // Exception 1: stub libraries and native bridge libraries are always available to platform
+ if cc, ok := mctx.Module().(*cc.Module); ok &&
+ (cc.IsStubs() || cc.Target().NativeBridge == android.NativeBridgeEnabled) {
+ availableToPlatform = true
+ }
+
+ // Exception 2: bootstrap bionic libraries are also always available to platform
+ if cc.InstallToBootstrap(mctx.ModuleName(), mctx.Config()) {
+ availableToPlatform = true
+ }
+
+ if !availableToPlatform {
+ am.SetNotAvailableForPlatform()
+ }
+ }
+}
+
// If a module in an APEX depends on a module from an SDK then it needs an APEX
// specific variant created for it. Refer to sdk.sdkDepsReplaceMutator.
func inAnySdk(module android.Module) bool {
@@ -1111,8 +1165,10 @@
IsCoverageVariant bool `blueprint:"mutated"`
// Whether this APEX is considered updatable or not. When set to true, this will enforce additional
- // rules for making sure that the APEX is truely updatable. This will also disable the size optimizations
- // like symlinking to the system libs. Default is false.
+ // rules for making sure that the APEX is truly updatable.
+ // - To be updatable, min_sdk_version should be set as well
+ // This will also disable the size optimizations like symlinking to the system libs.
+ // Default is false.
Updatable *bool
// The minimum SDK version that this apex must be compatible with.
@@ -1885,6 +1941,14 @@
})
}
+func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
+ if proptools.Bool(a.properties.Updatable) {
+ if String(a.properties.Min_sdk_version) == "" {
+ ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
+ }
+ }
+}
+
// Collects the list of module names that directly or indirectly contributes to the payload of this APEX
func (a *apexBundle) collectDepsInfo(ctx android.ModuleContext) {
a.depInfos = make(map[string]depInfo)
@@ -1950,6 +2014,7 @@
}
a.checkApexAvailability(ctx)
+ a.checkUpdatable(ctx)
a.collectDepsInfo(ctx)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index eed0d72..91ad6e8 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -3668,22 +3668,12 @@
}`)
}
-func TestApexAvailable_CreatedForPlatform(t *testing.T) {
- // check that libfoo and libbar are created only for myapex, but not for the platform
- // TODO(jiyong) the checks for the platform variant are removed because we now create
- // the platform variant regardless of the apex_availability. Instead, we will make sure that
- // the platform variants are not used from other platform modules. When that is done,
- // these checks will be replaced by expecting a specific error message that will be
- // emitted when the platform variant is used.
- // ensureListContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_shared_myapex")
- // ensureListNotContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_shared")
- // ensureListContains(t, ctx.ModuleVariantsForTests("libbar"), "android_arm64_armv8-a_shared_myapex")
- // ensureListNotContains(t, ctx.ModuleVariantsForTests("libbar"), "android_arm64_armv8-a_shared")
-
+func TestApexAvailable_CheckForPlatform(t *testing.T) {
ctx, _ := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
+ native_shared_libs: ["libbar", "libbaz"],
}
apex_key {
@@ -3696,16 +3686,52 @@
name: "libfoo",
stl: "none",
system_shared_libs: [],
+ shared_libs: ["libbar"],
apex_available: ["//apex_available:platform"],
+ }
+
+ cc_library {
+ name: "libfoo2",
+ stl: "none",
+ system_shared_libs: [],
+ shared_libs: ["libbaz"],
+ apex_available: ["//apex_available:platform"],
+ }
+
+ cc_library {
+ name: "libbar",
+ stl: "none",
+ system_shared_libs: [],
+ apex_available: ["myapex"],
+ }
+
+ cc_library {
+ name: "libbaz",
+ stl: "none",
+ system_shared_libs: [],
+ apex_available: ["myapex"],
+ stubs: {
+ versions: ["1"],
+ },
}`)
- // check that libfoo is created only for the platform
- ensureListNotContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_shared_myapex")
- ensureListContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_shared")
+ // libfoo shouldn't be available to platform even though it has "//apex_available:platform",
+ // because it depends on libbar which isn't available to platform
+ libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module)
+ if libfoo.NotAvailableForPlatform() != true {
+ t.Errorf("%q shouldn't be available to platform", libfoo.String())
+ }
+
+ // libfoo2 however can be available to platform because it depends on libbaz which provides
+ // stubs
+ libfoo2 := ctx.ModuleForTests("libfoo2", "android_arm64_armv8-a_shared").Module().(*cc.Module)
+ if libfoo2.NotAvailableForPlatform() == true {
+ t.Errorf("%q should be available to platform", libfoo2.String())
+ }
}
func TestApexAvailable_CreatedForApex(t *testing.T) {
- testApex(t, `
+ ctx, _ := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -3728,17 +3754,14 @@
},
}`)
- // shared variant of libfoo is only available to myapex
- // TODO(jiyong) the checks for the platform variant are removed because we now create
- // the platform variant regardless of the apex_availability. Instead, we will make sure that
- // the platform variants are not used from other platform modules. When that is done,
- // these checks will be replaced by expecting a specific error message that will be
- // emitted when the platform variant is used.
- // ensureListContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_shared_myapex")
- // ensureListNotContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_shared")
- // // but the static variant is available to both myapex and the platform
- // ensureListContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_static_myapex")
- // ensureListContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_static")
+ libfooShared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module)
+ if libfooShared.NotAvailableForPlatform() != true {
+ t.Errorf("%q shouldn't be available to platform", libfooShared.String())
+ }
+ libfooStatic := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Module().(*cc.Module)
+ if libfooStatic.NotAvailableForPlatform() != false {
+ t.Errorf("%q should be available to platform", libfooStatic.String())
+ }
}
func TestOverrideApex(t *testing.T) {
@@ -4017,6 +4040,7 @@
native_shared_libs: ["mylib"],
java_libs: ["myjar"],
updatable: true,
+ min_sdk_version: "current",
}
apex_key {
@@ -4242,6 +4266,22 @@
}
}
+func TestUpdatable_should_set_min_sdk_version(t *testing.T) {
+ testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ updatable: true,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ `)
+}
+
func TestNoUpdatableJarsInBootImage(t *testing.T) {
bp := `
java_library {
diff --git a/java/app_test.go b/java/app_test.go
index b1c8b63..39460dc 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2540,3 +2540,62 @@
t.Errorf("Unexpected LOCAL_OVERRIDES_PACKAGES value: %v, expected: %v", overrides, expectedOverrides)
}
}
+
+func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) {
+ ctx, config := testJava(t, `
+ java_defaults {
+ name: "rro_defaults",
+ theme: "default_theme",
+ product_specific: true,
+ aaptflags: ["--keep-raw-values"],
+ }
+
+ runtime_resource_overlay {
+ name: "foo_with_defaults",
+ defaults: ["rro_defaults"],
+ }
+
+ runtime_resource_overlay {
+ name: "foo_barebones",
+ }
+ `)
+
+ //
+ // RRO module with defaults
+ //
+ m := ctx.ModuleForTests("foo_with_defaults", "android_common")
+
+ // Check AAPT2 link flags.
+ aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ")
+ expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
+ absentFlags := android.RemoveListFromList(expectedFlags, aapt2Flags)
+ if len(absentFlags) > 0 {
+ t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
+ }
+
+ // Check device location.
+ path := android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
+ expectedPath := []string{"/tmp/target/product/test_device/product/overlay/default_theme"}
+ if !reflect.DeepEqual(path, expectedPath) {
+ t.Errorf("Unexpected LOCAL_MODULE_PATH value: %q, expected: %q", path, expectedPath)
+ }
+
+ //
+ // RRO module without defaults
+ //
+ m = ctx.ModuleForTests("foo_barebones", "android_common")
+
+ // Check AAPT2 link flags.
+ aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ")
+ unexpectedFlags := "--keep-raw-values"
+ if inList(unexpectedFlags, aapt2Flags) {
+ t.Errorf("unexpected value, %q is present in aapt2 link flags, %q", unexpectedFlags, aapt2Flags)
+ }
+
+ // Check device location.
+ path = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
+ expectedPath = []string{"/tmp/target/product/test_device/system/overlay"}
+ if !reflect.DeepEqual(path, expectedPath) {
+ t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
+ }
+}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 8f08f1f..7ac71a4 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -1524,40 +1524,35 @@
apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
- updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
+
+ if baselineFile.Valid() {
+ ctx.PropertyErrorf("current API check can't have a baseline file. (module %s)", ctx.ModuleName())
+ }
d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
rule := android.NewRuleBuilder()
+ // Diff command line.
+ // -F matches the closest "opening" line, such as "package xxx{"
+ // and " public class Yyy {".
+ diff := `diff -u -F '{ *$'`
+
rule.Command().Text("( true")
+ rule.Command().
+ Text(diff).
+ Input(apiFile).Input(d.apiFile)
- srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
- srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
-
- cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
- deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
-
- cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
- FlagWithInput("--check-compatibility:api:current ", apiFile).
- FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
-
- d.inclusionAnnotationsFlags(ctx, cmd)
- d.mergeAnnoDirFlags(ctx, cmd)
-
- if baselineFile.Valid() {
- cmd.FlagWithInput("--baseline ", baselineFile.Path())
- cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
- }
-
- zipSyncCleanupCmd(rule, srcJarDir)
+ rule.Command().
+ Text(diff).
+ Input(removedApiFile).Input(d.removedApiFile)
msg := fmt.Sprintf(`\n******************************\n`+
`You have tried to change the API from what has been previously approved.\n\n`+
`To make these errors go away, you have two choices:\n`+
- ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
- ` errors above.\n\n`+
- ` 2. You can update current.txt by executing the following command:\n`+
+ ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+
+ ` to the new methods, etc. shown in the above diff.\n\n`+
+ ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+
` make %s-update-current-api\n\n`+
` To submit the revised current.txt to the main Android repository,\n`+
` you will need approval.\n`+
@@ -1570,7 +1565,7 @@
Text("; exit 38").
Text(")")
- rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
+ rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "check current API")
d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
diff --git a/java/java.go b/java/java.go
index 1c2e22a..5d77807 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2745,6 +2745,7 @@
&sdkLibraryProperties{},
&DexImportProperties{},
&android.ApexProperties{},
+ &RuntimeResourceOverlayProperties{},
)
android.InitDefaultsModule(module)