Merge "Fix inconsistencies in the apex names used for the apex variations."
diff --git a/android/apex.go b/android/apex.go
index be9adc4..b9efe4e 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -91,6 +91,16 @@
var ApexInfoProvider = blueprint.NewMutatorProvider(ApexInfo{}, "apex")
+func (i ApexInfo) AddJSONData(d *map[string]interface{}) {
+ (*d)["Apex"] = map[string]interface{}{
+ "ApexVariationName": i.ApexVariationName,
+ "MinSdkVersion": i.MinSdkVersion,
+ "InApexModules": i.InApexModules,
+ "InApexVariants": i.InApexVariants,
+ "ForPrebuiltApex": i.ForPrebuiltApex,
+ }
+}
+
// mergedName gives the name of the alias variation that will be used when multiple apex variations
// of a module can be deduped into one variation. For example, if libfoo is included in both apex.a
// and apex.b, and if the two APEXes have the same min_sdk_version (say 29), then libfoo doesn't
diff --git a/android/module.go b/android/module.go
index f745a4a..07d82f1 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1190,6 +1190,10 @@
vintfFragmentsPaths Paths
}
+func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
+ (*d)["Android"] = map[string]interface{}{}
+}
+
func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {}
func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 43b7cbe..f3493bd 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -166,6 +166,7 @@
func InitPrebuiltModuleWithSrcSupplier(module PrebuiltInterface, srcsSupplier PrebuiltSrcsSupplier, srcsPropertyName string) {
p := module.Prebuilt()
module.AddProperties(&p.properties)
+ module.base().customizableProperties = module.GetProperties()
if srcsSupplier == nil {
panic(fmt.Errorf("srcsSupplier must not be nil"))
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index ced37fe..23524a5 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -259,6 +259,38 @@
}`,
prebuilt: []OsType{Android, BuildOs},
},
+ {
+ name: "prebuilt properties customizable",
+ replaceBp: true,
+ modules: `
+ source {
+ name: "foo",
+ deps: [":bar"],
+ }
+
+ soong_config_module_type {
+ name: "prebuilt_with_config",
+ module_type: "prebuilt",
+ config_namespace: "any_namespace",
+ bool_variables: ["bool_var"],
+ properties: ["prefer"],
+ }
+
+ prebuilt_with_config {
+ name: "bar",
+ prefer: true,
+ srcs: ["prebuilt_file"],
+ soong_config_variables: {
+ bool_var: {
+ prefer: false,
+ conditions_default: {
+ prefer: true,
+ },
+ },
+ },
+ }`,
+ prebuilt: []OsType{Android, BuildOs},
+ },
}
func TestPrebuilts(t *testing.T) {
@@ -394,6 +426,9 @@
ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
ctx.RegisterModuleType("source", newSourceModule)
ctx.RegisterModuleType("override_source", newOverrideSourceModule)
+ ctx.RegisterModuleType("soong_config_module_type", soongConfigModuleTypeFactory)
+ ctx.RegisterModuleType("soong_config_string_variable", soongConfigStringVariableDummyFactory)
+ ctx.RegisterModuleType("soong_config_bool_variable", soongConfigBoolVariableDummyFactory)
}
type prebuiltModule struct {
diff --git a/android/sdk.go b/android/sdk.go
index 5c58612..e700031 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -375,6 +375,8 @@
// SdkMemberType returns the SdkMemberType that will be used to automatically add the child module
// to the sdk.
+ //
+ // Returning nil will prevent the module being added to the sdk.
SdkMemberType(child Module) SdkMemberType
// ExportMember determines whether a module added to the sdk through this tag will be exported
diff --git a/androidmk/androidmk/androidmk_test.go b/androidmk/androidmk/androidmk_test.go
index 067dcba..02ab89d 100644
--- a/androidmk/androidmk/androidmk_test.go
+++ b/androidmk/androidmk/androidmk_test.go
@@ -794,7 +794,7 @@
include $(BUILD_CTS_SUPPORT_PACKAGE)
`,
expected: `
-android_test {
+android_test_helper_app {
name: "FooTest",
defaults: ["cts_support_defaults"],
test_suites: ["cts"],
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index 66bc9e0..8554c19 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -22,6 +22,7 @@
"android/soong/android"
"android/soong/java"
+ "github.com/google/blueprint/proptools"
)
// Contains tests for bootclasspath_fragment logic from java/bootclasspath_fragment.go as the ART
@@ -216,9 +217,9 @@
`,
)
- checkSdkKindStubs := func(message string, info java.HiddenAPIInfo, kind android.SdkKind, expectedPaths ...string) {
+ checkAPIScopeStubs := func(message string, info java.HiddenAPIInfo, apiScope *java.HiddenAPIScope, expectedPaths ...string) {
t.Helper()
- android.AssertPathsRelativeToTopEquals(t, fmt.Sprintf("%s %s", message, kind), expectedPaths, info.TransitiveStubDexJarsByKind[kind])
+ android.AssertPathsRelativeToTopEquals(t, fmt.Sprintf("%s %s", message, apiScope), expectedPaths, info.TransitiveStubDexJarsByScope[apiScope])
}
// Check stub dex paths exported by art.
@@ -229,10 +230,10 @@
bazSystemStubs := "out/soong/.intermediates/baz.stubs.system/android_common/dex/baz.stubs.system.jar"
bazTestStubs := "out/soong/.intermediates/baz.stubs.test/android_common/dex/baz.stubs.test.jar"
- checkSdkKindStubs("art", artInfo, android.SdkPublic, bazPublicStubs)
- checkSdkKindStubs("art", artInfo, android.SdkSystem, bazSystemStubs)
- checkSdkKindStubs("art", artInfo, android.SdkTest, bazTestStubs)
- checkSdkKindStubs("art", artInfo, android.SdkCorePlatform)
+ checkAPIScopeStubs("art", artInfo, java.PublicHiddenAPIScope, bazPublicStubs)
+ checkAPIScopeStubs("art", artInfo, java.SystemHiddenAPIScope, bazSystemStubs)
+ checkAPIScopeStubs("art", artInfo, java.TestHiddenAPIScope, bazTestStubs)
+ checkAPIScopeStubs("art", artInfo, java.CorePlatformHiddenAPIScope)
// Check stub dex paths exported by other.
otherFragment := result.Module("other-bootclasspath-fragment", "android_common")
@@ -241,10 +242,10 @@
fooPublicStubs := "out/soong/.intermediates/foo.stubs/android_common/dex/foo.stubs.jar"
fooSystemStubs := "out/soong/.intermediates/foo.stubs.system/android_common/dex/foo.stubs.system.jar"
- checkSdkKindStubs("other", otherInfo, android.SdkPublic, bazPublicStubs, fooPublicStubs)
- checkSdkKindStubs("other", otherInfo, android.SdkSystem, bazSystemStubs, fooSystemStubs)
- checkSdkKindStubs("other", otherInfo, android.SdkTest, bazTestStubs, fooSystemStubs)
- checkSdkKindStubs("other", otherInfo, android.SdkCorePlatform)
+ checkAPIScopeStubs("other", otherInfo, java.PublicHiddenAPIScope, bazPublicStubs, fooPublicStubs)
+ checkAPIScopeStubs("other", otherInfo, java.SystemHiddenAPIScope, bazSystemStubs, fooSystemStubs)
+ checkAPIScopeStubs("other", otherInfo, java.TestHiddenAPIScope, bazTestStubs, fooSystemStubs)
+ checkAPIScopeStubs("other", otherInfo, java.CorePlatformHiddenAPIScope)
}
func checkBootclasspathFragment(t *testing.T, result *android.TestResult, moduleName, variantName string, expectedConfiguredModules string, expectedBootclasspathFragmentFiles string) {
@@ -718,4 +719,480 @@
checkFragmentExportedDexJar("bar", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/bar.jar")
}
+func getDexJarPath(result *android.TestResult, name string) string {
+ module := result.Module(name, "android_common")
+ return module.(java.UsesLibraryDependency).DexJarBuildPath().RelativeToTop().String()
+}
+
+// TestBootclasspathFragment_HiddenAPIList checks to make sure that the correct parameters are
+// passed to the hiddenapi list tool.
+func TestBootclasspathFragment_HiddenAPIList(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForTestWithBootclasspathFragment,
+ prepareForTestWithArtApex,
+ prepareForTestWithMyapex,
+ // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
+ java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
+ java.FixtureConfigureUpdatableBootJars("myapex:foo", "myapex:bar"),
+ // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
+ // is disabled.
+ android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
+
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureWithLastReleaseApis("foo", "quuz"),
+ ).RunTestWithBp(t, `
+ apex {
+ name: "com.android.art",
+ key: "com.android.art.key",
+ bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "com.android.art.key",
+ public_key: "com.android.art.avbpubkey",
+ private_key: "com.android.art.pem",
+ }
+
+ java_library {
+ name: "baz",
+ apex_available: [
+ "com.android.art",
+ ],
+ srcs: ["b.java"],
+ compile_dex: true,
+ }
+
+ java_sdk_library {
+ name: "quuz",
+ apex_available: [
+ "com.android.art",
+ ],
+ srcs: ["b.java"],
+ compile_dex: true,
+ public: {enabled: true},
+ system: {enabled: true},
+ test: {enabled: true},
+ module_lib: {enabled: true},
+ }
+
+ bootclasspath_fragment {
+ name: "art-bootclasspath-fragment",
+ image_name: "art",
+ // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
+ contents: ["baz", "quuz"],
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ bootclasspath_fragments: [
+ "mybootclasspathfragment",
+ ],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_sdk_library {
+ name: "foo",
+ srcs: ["b.java"],
+ shared_library: false,
+ public: {enabled: true},
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ contents: [
+ "foo",
+ "bar",
+ ],
+ apex_available: [
+ "myapex",
+ ],
+ fragments: [
+ {
+ apex: "com.android.art",
+ module: "art-bootclasspath-fragment",
+ },
+ ],
+ }
+ `)
+
+ java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
+ "art-bootclasspath-fragment",
+ "bar",
+ "dex2oatd",
+ "foo",
+ })
+
+ fooStubs := getDexJarPath(result, "foo.stubs")
+ quuzPublicStubs := getDexJarPath(result, "quuz.stubs")
+ quuzSystemStubs := getDexJarPath(result, "quuz.stubs.system")
+ quuzTestStubs := getDexJarPath(result, "quuz.stubs.test")
+ quuzModuleLibStubs := getDexJarPath(result, "quuz.stubs.module_lib")
+
+ // Make sure that the fragment uses the quuz stub dex jars when generating the hidden API flags.
+ fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
+
+ rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
+ command := rule.RuleParams.Command
+ android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
+
+ // Make sure that the quuz stubs are available for resolving references from the implementation
+ // boot dex jars provided by this module.
+ android.AssertStringDoesContain(t, "quuz widest", command, "--dependency-stub-dex="+quuzModuleLibStubs)
+
+ // Make sure that the quuz stubs are available for resolving references from the different API
+ // stubs provided by this module.
+ android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+quuzPublicStubs+":"+fooStubs)
+ android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+quuzSystemStubs+":"+fooStubs)
+ android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+quuzTestStubs+":"+fooStubs)
+}
+
+// TestBootclasspathFragment_AndroidNonUpdatable checks to make sure that setting
+// additional_stubs: ["android-non-updatable"] causes the source android-non-updatable modules to be
+// added to the hiddenapi list tool.
+func TestBootclasspathFragment_AndroidNonUpdatable(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForTestWithBootclasspathFragment,
+ prepareForTestWithArtApex,
+ prepareForTestWithMyapex,
+ // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
+ java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "myapex:foo", "myapex:bar"),
+ // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
+ // is disabled.
+ android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
+
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureWithLastReleaseApis("foo", "android-non-updatable"),
+ ).RunTestWithBp(t, `
+ java_sdk_library {
+ name: "android-non-updatable",
+ srcs: ["b.java"],
+ compile_dex: true,
+ public: {
+ enabled: true,
+ },
+ system: {
+ enabled: true,
+ },
+ test: {
+ enabled: true,
+ },
+ module_lib: {
+ enabled: true,
+ },
+ }
+
+ apex {
+ name: "com.android.art",
+ key: "com.android.art.key",
+ bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ java_libs: [
+ "baz",
+ "quuz",
+ ],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "com.android.art.key",
+ public_key: "com.android.art.avbpubkey",
+ private_key: "com.android.art.pem",
+ }
+
+ java_library {
+ name: "baz",
+ apex_available: [
+ "com.android.art",
+ ],
+ srcs: ["b.java"],
+ compile_dex: true,
+ }
+
+ java_library {
+ name: "quuz",
+ apex_available: [
+ "com.android.art",
+ ],
+ srcs: ["b.java"],
+ compile_dex: true,
+ }
+
+ bootclasspath_fragment {
+ name: "art-bootclasspath-fragment",
+ image_name: "art",
+ // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
+ contents: ["baz", "quuz"],
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ bootclasspath_fragments: [
+ "mybootclasspathfragment",
+ ],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_sdk_library {
+ name: "foo",
+ srcs: ["b.java"],
+ shared_library: false,
+ public: {enabled: true},
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ contents: [
+ "foo",
+ "bar",
+ ],
+ apex_available: [
+ "myapex",
+ ],
+ additional_stubs: ["android-non-updatable"],
+ fragments: [
+ {
+ apex: "com.android.art",
+ module: "art-bootclasspath-fragment",
+ },
+ ],
+ }
+ `)
+
+ java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
+ "android-non-updatable.stubs",
+ "android-non-updatable.stubs.module_lib",
+ "android-non-updatable.stubs.system",
+ "android-non-updatable.stubs.test",
+ "art-bootclasspath-fragment",
+ "bar",
+ "dex2oatd",
+ "foo",
+ })
+
+ nonUpdatablePublicStubs := getDexJarPath(result, "android-non-updatable.stubs")
+ nonUpdatableSystemStubs := getDexJarPath(result, "android-non-updatable.stubs.system")
+ nonUpdatableTestStubs := getDexJarPath(result, "android-non-updatable.stubs.test")
+ nonUpdatableModuleLibStubs := getDexJarPath(result, "android-non-updatable.stubs.module_lib")
+
+ // Make sure that the fragment uses the android-non-updatable modules when generating the hidden
+ // API flags.
+ fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
+
+ rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
+ command := rule.RuleParams.Command
+ android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
+
+ // Make sure that the module_lib non-updatable stubs are available for resolving references from
+ // the implementation boot dex jars provided by this module.
+ android.AssertStringDoesContain(t, "android-non-updatable widest", command, "--dependency-stub-dex="+nonUpdatableModuleLibStubs)
+
+ // Make sure that the appropriate non-updatable stubs are available for resolving references from
+ // the different API stubs provided by this module.
+ android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+nonUpdatablePublicStubs)
+ android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+nonUpdatableSystemStubs)
+ android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+nonUpdatableTestStubs)
+}
+
+// TestBootclasspathFragment_AndroidNonUpdatable_AlwaysUsePrebuiltSdks checks to make sure that
+// setting additional_stubs: ["android-non-updatable"] causes the prebuilt android-non-updatable
+// modules to be added to the hiddenapi list tool.
+func TestBootclasspathFragment_AndroidNonUpdatable_AlwaysUsePrebuiltSdks(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForTestWithBootclasspathFragment,
+ java.PrepareForTestWithJavaDefaultModules,
+ prepareForTestWithArtApex,
+ prepareForTestWithMyapex,
+ // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
+ java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "myapex:foo", "myapex:bar"),
+ // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
+ // is disabled.
+ android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
+
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
+ }),
+
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureWithPrebuiltApis(map[string][]string{
+ "current": {"android-non-updatable"},
+ "30": {"foo"},
+ }),
+ ).RunTestWithBp(t, `
+ apex {
+ name: "com.android.art",
+ key: "com.android.art.key",
+ bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ java_libs: [
+ "baz",
+ "quuz",
+ ],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "com.android.art.key",
+ public_key: "com.android.art.avbpubkey",
+ private_key: "com.android.art.pem",
+ }
+
+ java_library {
+ name: "baz",
+ apex_available: [
+ "com.android.art",
+ ],
+ srcs: ["b.java"],
+ compile_dex: true,
+ }
+
+ java_library {
+ name: "quuz",
+ apex_available: [
+ "com.android.art",
+ ],
+ srcs: ["b.java"],
+ compile_dex: true,
+ }
+
+ bootclasspath_fragment {
+ name: "art-bootclasspath-fragment",
+ image_name: "art",
+ // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
+ contents: ["baz", "quuz"],
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ bootclasspath_fragments: [
+ "mybootclasspathfragment",
+ ],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_sdk_library {
+ name: "foo",
+ srcs: ["b.java"],
+ shared_library: false,
+ public: {enabled: true},
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ contents: [
+ "foo",
+ "bar",
+ ],
+ apex_available: [
+ "myapex",
+ ],
+ additional_stubs: ["android-non-updatable"],
+ fragments: [
+ {
+ apex: "com.android.art",
+ module: "art-bootclasspath-fragment",
+ },
+ ],
+ }
+ `)
+
+ java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
+ "art-bootclasspath-fragment",
+ "bar",
+ "dex2oatd",
+ "foo",
+ "prebuilt_sdk_module-lib_current_android-non-updatable",
+ "prebuilt_sdk_public_current_android-non-updatable",
+ "prebuilt_sdk_system_current_android-non-updatable",
+ "prebuilt_sdk_test_current_android-non-updatable",
+ })
+
+ nonUpdatablePublicStubs := getDexJarPath(result, "sdk_public_current_android-non-updatable")
+ nonUpdatableSystemStubs := getDexJarPath(result, "sdk_system_current_android-non-updatable")
+ nonUpdatableTestStubs := getDexJarPath(result, "sdk_test_current_android-non-updatable")
+ nonUpdatableModuleLibStubs := getDexJarPath(result, "sdk_module-lib_current_android-non-updatable")
+
+ // Make sure that the fragment uses the android-non-updatable modules when generating the hidden
+ // API flags.
+ fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
+
+ rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
+ command := rule.RuleParams.Command
+ android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
+
+ // Make sure that the module_lib non-updatable stubs are available for resolving references from
+ // the implementation boot dex jars provided by this module.
+ android.AssertStringDoesContain(t, "android-non-updatable widest", command, "--dependency-stub-dex="+nonUpdatableModuleLibStubs)
+
+ // Make sure that the appropriate non-updatable stubs are available for resolving references from
+ // the different API stubs provided by this module.
+ android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+nonUpdatablePublicStubs)
+ android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+nonUpdatableSystemStubs)
+ android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+nonUpdatableTestStubs)
+}
+
// TODO(b/177892522) - add test for host apex.
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index fae6101..9640024 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -319,7 +319,7 @@
var defStr string
switch mod.Type {
case "cts_support_package":
- mod.Type = "android_test"
+ mod.Type = "android_test_helper_app"
defStr = "cts_support_defaults"
case "cts_package":
mod.Type = "android_test"
@@ -622,12 +622,20 @@
func rewriteAndroidTest(f *Fixer) error {
for _, def := range f.tree.Defs {
mod, ok := def.(*parser.Module)
- if !(ok && mod.Type == "android_test") {
+ if !ok {
+ // The definition is not a module.
+ continue
+ }
+ if mod.Type != "android_test" && mod.Type != "android_test_helper_app" {
+ // The module is not an android_test or android_test_helper_app.
continue
}
// The rewriter converts LOCAL_MODULE_PATH attribute into a struct attribute
// 'local_module_path'. For the android_test module, it should be $(TARGET_OUT_DATA_APPS),
// that is, `local_module_path: { var: "TARGET_OUT_DATA_APPS"}`
+ // 1. if the `key: val` pair matches, (key is `local_module_path`,
+ // and val is `{ var: "TARGET_OUT_DATA_APPS"}`), this property is removed;
+ // 2. o/w, an error msg is thrown.
const local_module_path = "local_module_path"
if prop_local_module_path, ok := mod.GetProperty(local_module_path); ok {
removeProperty(mod, local_module_path)
@@ -637,7 +645,7 @@
continue
}
return indicateAttributeError(mod, "filename",
- "Only LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) is allowed for the android_test")
+ "Only LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) is allowed for the %s", mod.Type)
}
}
return nil
diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go
index 61dfe1a..ebfeb22 100644
--- a/bpfix/bpfix/bpfix_test.go
+++ b/bpfix/bpfix/bpfix_test.go
@@ -636,7 +636,7 @@
}
`,
out: `
- android_test {
+ android_test_helper_app {
name: "foo",
defaults: ["cts_support_defaults"],
}
diff --git a/cc/cc.go b/cc/cc.go
index fd4d89f..15cb39a 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -831,6 +831,46 @@
hideApexVariantFromMake bool
}
+func (c *Module) AddJSONData(d *map[string]interface{}) {
+ c.AndroidModuleBase().AddJSONData(d)
+ (*d)["Cc"] = map[string]interface{}{
+ "SdkVersion": c.SdkVersion(),
+ "MinSdkVersion": c.MinSdkVersion(),
+ "VndkVersion": c.VndkVersion(),
+ "ProductSpecific": c.ProductSpecific(),
+ "SocSpecific": c.SocSpecific(),
+ "DeviceSpecific": c.DeviceSpecific(),
+ "InProduct": c.InProduct(),
+ "InVendor": c.InVendor(),
+ "InRamdisk": c.InRamdisk(),
+ "InVendorRamdisk": c.InVendorRamdisk(),
+ "InRecovery": c.InRecovery(),
+ "VendorAvailable": c.VendorAvailable(),
+ "ProductAvailable": c.ProductAvailable(),
+ "RamdiskAvailable": c.RamdiskAvailable(),
+ "VendorRamdiskAvailable": c.VendorRamdiskAvailable(),
+ "RecoveryAvailable": c.RecoveryAvailable(),
+ "OdmAvailable": c.OdmAvailable(),
+ "InstallInData": c.InstallInData(),
+ "InstallInRamdisk": c.InstallInRamdisk(),
+ "InstallInSanitizerDir": c.InstallInSanitizerDir(),
+ "InstallInVendorRamdisk": c.InstallInVendorRamdisk(),
+ "InstallInRecovery": c.InstallInRecovery(),
+ "InstallInRoot": c.InstallInRoot(),
+ "IsVndk": c.IsVndk(),
+ "IsVndkExt": c.IsVndkExt(),
+ "IsVndkPrivate": c.IsVndkPrivate(),
+ "IsVndkSp": c.IsVndkSp(),
+ "IsLlndk": c.IsLlndk(),
+ "IsLlndkPublic": c.IsLlndkPublic(),
+ "IsSnapshotLibrary": c.IsSnapshotLibrary(),
+ "IsSnapshotPrebuilt": c.IsSnapshotPrebuilt(),
+ "IsVendorPublicLibrary": c.IsVendorPublicLibrary(),
+ "ApexSdkVersion": c.apexSdkVersion,
+ "TestFor": c.TestFor(),
+ }
+}
+
func (c *Module) SetPreventInstall() {
c.Properties.PreventInstall = true
}
diff --git a/cc/config/global.go b/cc/config/global.go
index 24e10a4..4957767 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -46,6 +46,7 @@
"-O2",
"-g",
+ "-fdebug-default-version=5",
"-fdebug-info-for-profiling",
"-fno-strict-aliasing",
@@ -145,8 +146,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r416183b"
- ClangDefaultShortVersion = "12.0.5"
+ ClangDefaultVersion = "clang-r416183b1"
+ ClangDefaultShortVersion = "12.0.7"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
diff --git a/dexpreopt/OWNERS b/dexpreopt/OWNERS
index 166472f..5a2a198 100644
--- a/dexpreopt/OWNERS
+++ b/dexpreopt/OWNERS
@@ -1 +1 @@
-per-file * = ngeoffray@google.com,calin@google.com,mathieuc@google.com
+per-file * = ngeoffray@google.com,calin@google.com,skvadrik@google.com
diff --git a/java/OWNERS b/java/OWNERS
index 16ef4d8..5242712 100644
--- a/java/OWNERS
+++ b/java/OWNERS
@@ -1 +1 @@
-per-file dexpreopt*.go = ngeoffray@google.com,calin@google.com,mathieuc@google.com
+per-file dexpreopt*.go = ngeoffray@google.com,calin@google.com,skvadrik@google.com
diff --git a/java/bootclasspath.go b/java/bootclasspath.go
index ccb69a0..4108770 100644
--- a/java/bootclasspath.go
+++ b/java/bootclasspath.go
@@ -227,13 +227,13 @@
Core_platform_api BootclasspathNestedAPIProperties
}
-// sdkKindToStubLibs calculates the stub library modules for each relevant android.SdkKind from the
+// apiScopeToStubLibs calculates the stub library modules for each relevant *HiddenAPIScope from the
// Stub_libs properties.
-func (p BootclasspathAPIProperties) sdkKindToStubLibs() map[android.SdkKind][]string {
- m := map[android.SdkKind][]string{}
- for _, kind := range []android.SdkKind{android.SdkPublic, android.SdkSystem, android.SdkTest} {
- m[kind] = p.Api.Stub_libs
+func (p BootclasspathAPIProperties) apiScopeToStubLibs() map[*HiddenAPIScope][]string {
+ m := map[*HiddenAPIScope][]string{}
+ for _, apiScope := range hiddenAPISdkLibrarySupportedScopes {
+ m[apiScope] = p.Api.Stub_libs
}
- m[android.SdkCorePlatform] = p.Core_platform_api.Stub_libs
+ m[CorePlatformHiddenAPIScope] = p.Core_platform_api.Stub_libs
return m
}
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index c7249b0..8ea9f82 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -121,8 +121,18 @@
BootclasspathFragmentCoverageAffectedProperties
Coverage BootclasspathFragmentCoverageAffectedProperties
+ // Hidden API related properties.
Hidden_api HiddenAPIFlagFileProperties
+ // The list of additional stub libraries which this fragment's contents use but which are not
+ // provided by another bootclasspath_fragment.
+ //
+ // Note, "android-non-updatable" is treated specially. While no such module exists it is treated
+ // as if it was a java_sdk_library. So, when public API stubs are needed then it will be replaced
+ // with "android-non-updatable.stubs", with "androidn-non-updatable.system.stubs" when the system
+ // stubs are needed and so on.
+ Additional_stubs []string
+
// Properties that allow a fragment to depend on other fragments. This is needed for hidden API
// processing as it needs access to all the classes used by a fragment including those provided
// by other fragments.
@@ -378,7 +388,16 @@
func (b *BootclasspathFragmentModule) DepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependencies onto all the modules that provide the API stubs for classes on this
// bootclasspath fragment.
- hiddenAPIAddStubLibDependencies(ctx, b.properties.sdkKindToStubLibs())
+ hiddenAPIAddStubLibDependencies(ctx, b.properties.apiScopeToStubLibs())
+
+ for _, additionalStubModule := range b.properties.Additional_stubs {
+ for _, apiScope := range hiddenAPISdkLibrarySupportedScopes {
+ // Add a dependency onto a possibly scope specific stub library.
+ scopeSpecificDependency := apiScope.scopeSpecificStubModule(ctx, additionalStubModule)
+ tag := hiddenAPIStubsDependencyTag{apiScope: apiScope, fromAdditionalDependency: true}
+ ctx.AddVariationDependencies(nil, tag, scopeSpecificDependency)
+ }
+ }
if SkipDexpreoptBootJars(ctx) {
return
@@ -595,7 +614,7 @@
// Other bootclasspath_fragments that depend on this need the transitive set of stub dex jars
// from this to resolve any references from their code to classes provided by this fragment
// and the fragments this depends upon.
- TransitiveStubDexJarsByKind: input.transitiveStubDexJarsByKind(),
+ TransitiveStubDexJarsByScope: input.transitiveStubDexJarsByScope(),
}
// The monolithic hidden API processing also needs access to all the output files produced by
@@ -639,8 +658,8 @@
// Populate with flag file paths from the properties.
input.extractFlagFilesFromProperties(ctx, &b.properties.Hidden_api)
- // Store the stub dex jars from this module's fragment dependencies.
- input.DependencyStubDexJarsByKind = dependencyHiddenApiInfo.TransitiveStubDexJarsByKind
+ // Add the stub dex jars from this module's fragment dependencies.
+ input.DependencyStubDexJarsByScope.append(dependencyHiddenApiInfo.TransitiveStubDexJarsByScope)
return input
}
diff --git a/java/bootclasspath_fragment_test.go b/java/bootclasspath_fragment_test.go
index fba7d1a..aa1c59f 100644
--- a/java/bootclasspath_fragment_test.go
+++ b/java/bootclasspath_fragment_test.go
@@ -245,17 +245,17 @@
otherPublicStubsJar := "out/soong/.intermediates/myothersdklibrary.stubs/android_common/dex/myothersdklibrary.stubs.jar"
// Check that SdkPublic uses public stubs for all sdk libraries.
- android.AssertPathsRelativeToTopEquals(t, "public dex stubs jar", []string{otherPublicStubsJar, publicStubsJar, stubsJar}, info.TransitiveStubDexJarsByKind[android.SdkPublic])
+ android.AssertPathsRelativeToTopEquals(t, "public dex stubs jar", []string{otherPublicStubsJar, publicStubsJar, stubsJar}, info.TransitiveStubDexJarsByScope[PublicHiddenAPIScope])
// Check that SdkSystem uses system stubs for mysdklibrary and public stubs for myothersdklibrary
// as it does not provide system stubs.
- android.AssertPathsRelativeToTopEquals(t, "system dex stubs jar", []string{otherPublicStubsJar, systemStubsJar, stubsJar}, info.TransitiveStubDexJarsByKind[android.SdkSystem])
+ android.AssertPathsRelativeToTopEquals(t, "system dex stubs jar", []string{otherPublicStubsJar, systemStubsJar, stubsJar}, info.TransitiveStubDexJarsByScope[SystemHiddenAPIScope])
// Check that SdkTest also uses system stubs for mysdklibrary as it does not provide test stubs
// and public stubs for myothersdklibrary as it does not provide test stubs either.
- android.AssertPathsRelativeToTopEquals(t, "test dex stubs jar", []string{otherPublicStubsJar, systemStubsJar, stubsJar}, info.TransitiveStubDexJarsByKind[android.SdkTest])
+ android.AssertPathsRelativeToTopEquals(t, "test dex stubs jar", []string{otherPublicStubsJar, systemStubsJar, stubsJar}, info.TransitiveStubDexJarsByScope[TestHiddenAPIScope])
// Check that SdkCorePlatform uses public stubs from the mycoreplatform library.
corePlatformStubsJar := "out/soong/.intermediates/mycoreplatform.stubs/android_common/dex/mycoreplatform.stubs.jar"
- android.AssertPathsRelativeToTopEquals(t, "core platform dex stubs jar", []string{corePlatformStubsJar}, info.TransitiveStubDexJarsByKind[android.SdkCorePlatform])
+ android.AssertPathsRelativeToTopEquals(t, "core platform dex stubs jar", []string{corePlatformStubsJar}, info.TransitiveStubDexJarsByScope[CorePlatformHiddenAPIScope])
}
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index 6e22614..ba53ea6 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -25,9 +25,160 @@
// Contains support for processing hiddenAPI in a modular fashion.
+// HiddenAPIScope encapsulates all the information that the hidden API processing needs about API
+// scopes, i.e. what is called android.SdkKind and apiScope. It does not just use those as they do
+// not provide the information needed by hidden API processing.
+type HiddenAPIScope struct {
+ // The name of the scope, used for debug purposes.
+ name string
+
+ // The corresponding android.SdkKind, used for retrieving paths from java_sdk_library* modules.
+ sdkKind android.SdkKind
+
+ // The option needed to passed to "hiddenapi list".
+ hiddenAPIListOption string
+
+ // The name sof the source stub library modules that contain the API provided by the platform,
+ // i.e. by modules that are not in an APEX.
+ nonUpdatableSourceModule string
+
+ // The names of the prebuilt stub library modules that contain the API provided by the platform,
+ // i.e. by modules that are not in an APEX.
+ nonUpdatablePrebuiltModule string
+}
+
+// initHiddenAPIScope initializes the scope.
+func initHiddenAPIScope(apiScope *HiddenAPIScope) *HiddenAPIScope {
+ sdkKind := apiScope.sdkKind
+ // The platform does not provide a core platform API.
+ if sdkKind != android.SdkCorePlatform {
+ kindAsString := sdkKind.String()
+ var insert string
+ if sdkKind == android.SdkPublic {
+ insert = ""
+ } else {
+ insert = "." + strings.ReplaceAll(kindAsString, "-", "_")
+ }
+
+ nonUpdatableModule := "android-non-updatable"
+
+ // Construct the name of the android-non-updatable source module for this scope.
+ apiScope.nonUpdatableSourceModule = fmt.Sprintf("%s.stubs%s", nonUpdatableModule, insert)
+
+ prebuiltModuleName := func(name string, kind string) string {
+ return fmt.Sprintf("sdk_%s_current_%s", kind, name)
+ }
+
+ // Construct the name of the android-non-updatable prebuilt module for this scope.
+ apiScope.nonUpdatablePrebuiltModule = prebuiltModuleName(nonUpdatableModule, kindAsString)
+ }
+
+ return apiScope
+}
+
+// android-non-updatable takes the name of a module and returns a possibly scope specific name of
+// the module.
+func (l *HiddenAPIScope) scopeSpecificStubModule(ctx android.BaseModuleContext, name string) string {
+ // The android-non-updatable is not a java_sdk_library but there are separate stub libraries for
+ // each scope.
+ // TODO(b/192067200): Remove special handling of android-non-updatable.
+ if name == "android-non-updatable" {
+ if ctx.Config().AlwaysUsePrebuiltSdks() {
+ return l.nonUpdatablePrebuiltModule
+ } else {
+ return l.nonUpdatableSourceModule
+ }
+ } else {
+ // Assume that the module is either a java_sdk_library (or equivalent) and so will provide
+ // separate stub jars for each scope or is a java_library (or equivalent) in which case it will
+ // have the same stub jar for each scope.
+ return name
+ }
+}
+
+func (l *HiddenAPIScope) String() string {
+ return fmt.Sprintf("HiddenAPIScope{%s}", l.name)
+}
+
+var (
+ PublicHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{
+ name: "public",
+ sdkKind: android.SdkPublic,
+ hiddenAPIListOption: "--public-stub-classpath",
+ })
+ SystemHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{
+ name: "system",
+ sdkKind: android.SdkSystem,
+ hiddenAPIListOption: "--system-stub-classpath",
+ })
+ TestHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{
+ name: "test",
+ sdkKind: android.SdkTest,
+ hiddenAPIListOption: "--test-stub-classpath",
+ })
+ ModuleLibHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{
+ name: "module-lib",
+ sdkKind: android.SdkModule,
+ })
+ CorePlatformHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{
+ name: "core-platform",
+ sdkKind: android.SdkCorePlatform,
+ hiddenAPIListOption: "--core-platform-stub-classpath",
+ })
+
+ // hiddenAPIRelevantSdkKinds lists all the android.SdkKind instances that are needed by the hidden
+ // API processing.
+ //
+ // These are roughly in order from narrowest API surface to widest. Widest means the API stubs
+ // with the biggest API surface, e.g. test is wider than system is wider than public.
+ //
+ // Core platform is considered wider than system/module-lib because those modules that provide
+ // core platform APIs either do not have any system/module-lib APIs at all, or if they do it is
+ // because the core platform API is being converted to system/module-lib APIs. In either case the
+ // system/module-lib APIs are subsets of the core platform API.
+ //
+ // This is not strictly in order from narrowest to widest as the Test API is wider than system but
+ // is neither wider or narrower than the module-lib or core platform APIs. However, this works
+ // well enough at the moment.
+ // TODO(b/191644675): Correctly reflect the sub/superset relationships between APIs.
+ hiddenAPIScopes = []*HiddenAPIScope{
+ PublicHiddenAPIScope,
+ SystemHiddenAPIScope,
+ TestHiddenAPIScope,
+ ModuleLibHiddenAPIScope,
+ CorePlatformHiddenAPIScope,
+ }
+
+ // The HiddenAPIScope instances that are supported by a java_sdk_library.
+ //
+ // CorePlatformHiddenAPIScope is not used as the java_sdk_library does not have special support
+ // for core_platform API, instead it is implemented as a customized form of PublicHiddenAPIScope.
+ hiddenAPISdkLibrarySupportedScopes = []*HiddenAPIScope{
+ PublicHiddenAPIScope,
+ SystemHiddenAPIScope,
+ TestHiddenAPIScope,
+ ModuleLibHiddenAPIScope,
+ }
+
+ // The HiddenAPIScope instances that are supported by the `hiddenapi list`.
+ hiddenAPIFlagScopes = []*HiddenAPIScope{
+ PublicHiddenAPIScope,
+ SystemHiddenAPIScope,
+ TestHiddenAPIScope,
+ CorePlatformHiddenAPIScope,
+ }
+)
+
type hiddenAPIStubsDependencyTag struct {
blueprint.BaseDependencyTag
- sdkKind android.SdkKind
+
+ // The api scope for which this dependency was added.
+ apiScope *HiddenAPIScope
+
+ // Indicates that the dependency is not for an API provided by the current bootclasspath fragment
+ // but is an additional API provided by a module that is not part of the current bootclasspath
+ // fragment.
+ fromAdditionalDependency bool
}
func (b hiddenAPIStubsDependencyTag) ExcludeFromApexContents() {
@@ -38,6 +189,11 @@
}
func (b hiddenAPIStubsDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType {
+ // Do not add additional dependencies to the sdk.
+ if b.fromAdditionalDependency {
+ return nil
+ }
+
// If the module is a java_sdk_library then treat it as if it was specific in the java_sdk_libs
// property, otherwise treat if it was specified in the java_header_libs property.
if javaSdkLibrarySdkMemberType.IsInstance(child) {
@@ -65,24 +221,9 @@
var _ android.ExcludeFromApexContentsTag = hiddenAPIStubsDependencyTag{}
var _ android.SdkMemberTypeDependencyTag = hiddenAPIStubsDependencyTag{}
-// hiddenAPIRelevantSdkKinds lists all the android.SdkKind instances that are needed by the hidden
-// API processing.
-//
-// These are in order from narrowest API surface to widest. Widest means the API stubs with the
-// biggest API surface, e.g. test is wider than system is wider than public. Core platform is
-// considered wider than test even though it has no relationship with test because the libraries
-// that provide core platform API don't provide test. While the core platform API is being converted
-// to a system API the system API is still a subset of core platform.
-var hiddenAPIRelevantSdkKinds = []android.SdkKind{
- android.SdkPublic,
- android.SdkSystem,
- android.SdkTest,
- android.SdkCorePlatform,
-}
-
// hiddenAPIComputeMonolithicStubLibModules computes the set of module names that provide stubs
// needed to produce the hidden API monolithic stub flags file.
-func hiddenAPIComputeMonolithicStubLibModules(config android.Config) map[android.SdkKind][]string {
+func hiddenAPIComputeMonolithicStubLibModules(config android.Config) map[*HiddenAPIScope][]string {
var publicStubModules []string
var systemStubModules []string
var testStubModules []string
@@ -115,22 +256,22 @@
testStubModules = append(testStubModules, "jacoco-stubs")
}
- m := map[android.SdkKind][]string{}
- m[android.SdkPublic] = publicStubModules
- m[android.SdkSystem] = systemStubModules
- m[android.SdkTest] = testStubModules
- m[android.SdkCorePlatform] = corePlatformStubModules
+ m := map[*HiddenAPIScope][]string{}
+ m[PublicHiddenAPIScope] = publicStubModules
+ m[SystemHiddenAPIScope] = systemStubModules
+ m[TestHiddenAPIScope] = testStubModules
+ m[CorePlatformHiddenAPIScope] = corePlatformStubModules
return m
}
// hiddenAPIAddStubLibDependencies adds dependencies onto the modules specified in
-// sdkKindToStubLibModules. It adds them in a well known order and uses an SdkKind specific tag to
-// identify the source of the dependency.
-func hiddenAPIAddStubLibDependencies(ctx android.BottomUpMutatorContext, sdkKindToStubLibModules map[android.SdkKind][]string) {
+// apiScopeToStubLibModules. It adds them in a well known order and uses a HiddenAPIScope specific
+// tag to identify the source of the dependency.
+func hiddenAPIAddStubLibDependencies(ctx android.BottomUpMutatorContext, apiScopeToStubLibModules map[*HiddenAPIScope][]string) {
module := ctx.Module()
- for _, sdkKind := range hiddenAPIRelevantSdkKinds {
- modules := sdkKindToStubLibModules[sdkKind]
- ctx.AddDependency(module, hiddenAPIStubsDependencyTag{sdkKind: sdkKind}, modules...)
+ for _, apiScope := range hiddenAPIScopes {
+ modules := apiScopeToStubLibModules[apiScope]
+ ctx.AddDependency(module, hiddenAPIStubsDependencyTag{apiScope: apiScope}, modules...)
}
}
@@ -153,33 +294,21 @@
return dexJar
}
-var sdkKindToHiddenapiListOption = map[android.SdkKind]string{
- android.SdkPublic: "public-stub-classpath",
- android.SdkSystem: "system-stub-classpath",
- android.SdkTest: "test-stub-classpath",
- android.SdkCorePlatform: "core-platform-stub-classpath",
-}
-
-// ruleToGenerateHiddenAPIStubFlagsFile creates a rule to create a hidden API stub flags file.
+// buildRuleToGenerateHiddenAPIStubFlagsFile creates a rule to create a hidden API stub flags file.
//
// The rule is initialized but not built so that the caller can modify it and select an appropriate
// name.
-func ruleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, outputPath android.WritablePath, bootDexJars android.Paths, input HiddenAPIFlagInput) *android.RuleBuilder {
+func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, bootDexJars android.Paths, input HiddenAPIFlagInput, moduleStubFlagsPaths android.Paths) {
// Singleton rule which applies hiddenapi on all boot class path dex files.
rule := android.NewRuleBuilder(pctx, ctx)
tempPath := tempPathForRestat(ctx, outputPath)
// Find the widest API stubs provided by the fragments on which this depends, if any.
- var dependencyStubDexJars android.Paths
- for i := len(hiddenAPIRelevantSdkKinds) - 1; i >= 0; i-- {
- kind := hiddenAPIRelevantSdkKinds[i]
- stubsForKind := input.DependencyStubDexJarsByKind[kind]
- if len(stubsForKind) != 0 {
- dependencyStubDexJars = stubsForKind
- break
- }
- }
+ dependencyStubDexJars := input.DependencyStubDexJarsByScope.stubDexJarsForWidestAPIScope()
+
+ // Add widest API stubs from the additional dependencies of this, if any.
+ dependencyStubDexJars = append(dependencyStubDexJars, input.AdditionalStubDexJarsByScope.stubDexJarsForWidestAPIScope()...)
command := rule.Command().
Tool(ctx.Config().HostToolPath(ctx, "hiddenapi")).
@@ -187,24 +316,39 @@
FlagForEachInput("--dependency-stub-dex=", dependencyStubDexJars).
FlagForEachInput("--boot-dex=", bootDexJars)
- // Iterate over the sdk kinds in a fixed order.
- for _, sdkKind := range hiddenAPIRelevantSdkKinds {
- // Merge in the stub dex jar paths for this kind from the fragments on which it depends. They
- // will be needed to resolve dependencies from this fragment's stubs to classes in the other
- // fragment's APIs.
- dependencyPaths := input.DependencyStubDexJarsByKind[sdkKind]
- paths := append(dependencyPaths, input.StubDexJarsByKind[sdkKind]...)
+ // Iterate over the api scopes in a fixed order.
+ for _, apiScope := range hiddenAPIFlagScopes {
+ // Merge in the stub dex jar paths for this api scope from the fragments on which it depends.
+ // They will be needed to resolve dependencies from this fragment's stubs to classes in the
+ // other fragment's APIs.
+ var paths android.Paths
+ paths = append(paths, input.DependencyStubDexJarsByScope[apiScope]...)
+ paths = append(paths, input.AdditionalStubDexJarsByScope[apiScope]...)
+ paths = append(paths, input.StubDexJarsByScope[apiScope]...)
if len(paths) > 0 {
- option := sdkKindToHiddenapiListOption[sdkKind]
- command.FlagWithInputList("--"+option+"=", paths, ":")
+ option := apiScope.hiddenAPIListOption
+ command.FlagWithInputList(option+"=", paths, ":")
}
}
// Add the output path.
command.FlagWithOutput("--out-api-flags=", tempPath)
+ // If there are stub flag files that have been generated by fragments on which this depends then
+ // use them to validate the stub flag file generated by the rules created by this method.
+ if len(moduleStubFlagsPaths) > 0 {
+ validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, moduleStubFlagsPaths)
+
+ // Add the file that indicates that the file generated by this is valid.
+ //
+ // This will cause the validation rule above to be run any time that the output of this rule
+ // changes but the validation will run in parallel with other rules that depend on this file.
+ command.Validation(validFile)
+ }
+
commitChangeForRestat(rule, tempPath, outputPath)
- return rule
+
+ rule.Build(name, desc)
}
// HiddenAPIFlagFileProperties contains paths to the flag files that can be used to augment the
@@ -377,8 +521,8 @@
// that category.
FlagFilesByCategory FlagFilesByCategory
- // The paths to the stub dex jars for each of the android.SdkKind in hiddenAPIRelevantSdkKinds.
- TransitiveStubDexJarsByKind StubDexJarsByKind
+ // The paths to the stub dex jars for each of the *HiddenAPIScope in hiddenAPIScopes.
+ TransitiveStubDexJarsByScope StubDexJarsByScope
// The output from the hidden API processing needs to be made available to other modules.
HiddenAPIFlagOutput
@@ -386,8 +530,8 @@
func newHiddenAPIInfo() *HiddenAPIInfo {
info := HiddenAPIInfo{
- FlagFilesByCategory: FlagFilesByCategory{},
- TransitiveStubDexJarsByKind: StubDexJarsByKind{},
+ FlagFilesByCategory: FlagFilesByCategory{},
+ TransitiveStubDexJarsByScope: StubDexJarsByScope{},
}
return &info
}
@@ -398,36 +542,50 @@
for _, fragment := range fragments {
if ctx.OtherModuleHasProvider(fragment, HiddenAPIInfoProvider) {
info := ctx.OtherModuleProvider(fragment, HiddenAPIInfoProvider).(HiddenAPIInfo)
- i.TransitiveStubDexJarsByKind.append(info.TransitiveStubDexJarsByKind)
+ i.TransitiveStubDexJarsByScope.append(info.TransitiveStubDexJarsByScope)
}
}
// Dedup and sort paths.
- i.TransitiveStubDexJarsByKind.dedupAndSort()
+ i.TransitiveStubDexJarsByScope.dedupAndSort()
}
var HiddenAPIInfoProvider = blueprint.NewProvider(HiddenAPIInfo{})
-// StubDexJarsByKind maps an android.SdkKind to the paths to stub dex jars appropriate for that
-// level. See hiddenAPIRelevantSdkKinds for a list of the acceptable android.SdkKind values.
-type StubDexJarsByKind map[android.SdkKind]android.Paths
+// StubDexJarsByScope maps a *HiddenAPIScope to the paths to stub dex jars appropriate for that
+// scope. See hiddenAPIScopes for a list of the acceptable *HiddenAPIScope values.
+type StubDexJarsByScope map[*HiddenAPIScope]android.Paths
-// append appends the supplied kind specific stub dex jar pargs to the corresponding kind in this
+// append appends the API scope specific stub dex jar args to the corresponding scope in this
// map.
-func (s StubDexJarsByKind) append(other StubDexJarsByKind) {
- for _, kind := range hiddenAPIRelevantSdkKinds {
- s[kind] = append(s[kind], other[kind]...)
+func (s StubDexJarsByScope) append(other StubDexJarsByScope) {
+ for _, scope := range hiddenAPIScopes {
+ s[scope] = append(s[scope], other[scope]...)
}
}
// dedupAndSort removes duplicates in the stub dex jar paths and sorts them into a consistent and
// deterministic order.
-func (s StubDexJarsByKind) dedupAndSort() {
- for kind, paths := range s {
- s[kind] = android.SortedUniquePaths(paths)
+func (s StubDexJarsByScope) dedupAndSort() {
+ for apiScope, paths := range s {
+ s[apiScope] = android.SortedUniquePaths(paths)
}
}
+// stubDexJarsForWidestAPIScope returns the stub dex jars for the widest API scope provided by this
+// map. The relative width of APIs is determined by their order in hiddenAPIScopes.
+func (s StubDexJarsByScope) stubDexJarsForWidestAPIScope() android.Paths {
+ for i := len(hiddenAPIScopes) - 1; i >= 0; i-- {
+ apiScope := hiddenAPIScopes[i]
+ stubsForAPIScope := s[apiScope]
+ if len(stubsForAPIScope) != 0 {
+ return stubsForAPIScope
+ }
+ }
+
+ return nil
+}
+
// HiddenAPIFlagInput encapsulates information obtained from a module and its dependencies that are
// needed for hidden API flag generation.
type HiddenAPIFlagInput struct {
@@ -435,14 +593,21 @@
// from the stub dex files.
FlagFilesByCategory FlagFilesByCategory
- // StubDexJarsByKind contains the stub dex jars for different android.SdkKind and which determine
+ // StubDexJarsByScope contains the stub dex jars for different *HiddenAPIScope and which determine
// the initial flags for each dex member.
- StubDexJarsByKind StubDexJarsByKind
+ StubDexJarsByScope StubDexJarsByScope
- // DependencyStubDexJarsByKind contains the stub dex jars provided by the fragments on which this
- // depends. It is the result of merging HiddenAPIInfo.TransitiveStubDexJarsByKind from each
+ // DependencyStubDexJarsByScope contains the stub dex jars provided by the fragments on which this
+ // depends. It is the result of merging HiddenAPIInfo.TransitiveStubDexJarsByScope from each
// fragment on which this depends.
- DependencyStubDexJarsByKind StubDexJarsByKind
+ DependencyStubDexJarsByScope StubDexJarsByScope
+
+ // AdditionalStubDexJarsByScope contains stub dex jars provided by other modules in addition to
+ // the ones that are obtained from fragments on which this depends.
+ //
+ // These are kept separate from stub dex jars in HiddenAPIFlagInput.DependencyStubDexJarsByScope
+ // as there are not propagated transitively to other fragments that depend on this.
+ AdditionalStubDexJarsByScope StubDexJarsByScope
// RemovedTxtFiles is the list of removed.txt files provided by java_sdk_library modules that are
// specified in the bootclasspath_fragment's stub_libs and contents properties.
@@ -452,8 +617,10 @@
// newHiddenAPIFlagInput creates a new initialize HiddenAPIFlagInput struct.
func newHiddenAPIFlagInput() HiddenAPIFlagInput {
input := HiddenAPIFlagInput{
- FlagFilesByCategory: FlagFilesByCategory{},
- StubDexJarsByKind: StubDexJarsByKind{},
+ FlagFilesByCategory: FlagFilesByCategory{},
+ StubDexJarsByScope: StubDexJarsByScope{},
+ DependencyStubDexJarsByScope: StubDexJarsByScope{},
+ AdditionalStubDexJarsByScope: StubDexJarsByScope{},
}
return input
@@ -469,7 +636,7 @@
// required as the whole point of adding something to the bootclasspath fragment is to add it to
// the bootclasspath in order to be used by something else in the system. Without any stubs it
// cannot do that.
- if len(i.StubDexJarsByKind) == 0 {
+ if len(i.StubDexJarsByScope) == 0 {
return false
}
@@ -500,14 +667,15 @@
//
// That includes paths to the stub dex jars as well as paths to the *removed.txt files.
func (i *HiddenAPIFlagInput) gatherStubLibInfo(ctx android.ModuleContext, contents []android.Module) {
- addFromModule := func(ctx android.ModuleContext, module android.Module, kind android.SdkKind) {
- dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module, kind)
+ addFromModule := func(ctx android.ModuleContext, module android.Module, apiScope *HiddenAPIScope) {
+ sdkKind := apiScope.sdkKind
+ dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module, sdkKind)
if dexJar != nil {
- i.StubDexJarsByKind[kind] = append(i.StubDexJarsByKind[kind], dexJar)
+ i.StubDexJarsByScope[apiScope] = append(i.StubDexJarsByScope[apiScope], dexJar)
}
if sdkLibrary, ok := module.(SdkLibraryDependency); ok {
- removedTxtFile := sdkLibrary.SdkRemovedTxtFile(ctx, kind)
+ removedTxtFile := sdkLibrary.SdkRemovedTxtFile(ctx, sdkKind)
i.RemovedTxtFiles = append(i.RemovedTxtFiles, removedTxtFile.AsPaths()...)
}
}
@@ -515,11 +683,9 @@
// If the contents includes any java_sdk_library modules then add them to the stubs.
for _, module := range contents {
if _, ok := module.(SdkLibraryDependency); ok {
- // Add information for every possible kind needed by hidden API. SdkCorePlatform is not used
- // as the java_sdk_library does not have special support for core_platform API, instead it is
- // implemented as a customized form of SdkPublic.
- for _, kind := range []android.SdkKind{android.SdkPublic, android.SdkSystem, android.SdkTest} {
- addFromModule(ctx, module, kind)
+ // Add information for every possible API scope needed by hidden API.
+ for _, apiScope := range hiddenAPISdkLibrarySupportedScopes {
+ addFromModule(ctx, module, apiScope)
}
}
}
@@ -527,13 +693,21 @@
ctx.VisitDirectDeps(func(module android.Module) {
tag := ctx.OtherModuleDependencyTag(module)
if hiddenAPIStubsTag, ok := tag.(hiddenAPIStubsDependencyTag); ok {
- kind := hiddenAPIStubsTag.sdkKind
- addFromModule(ctx, module, kind)
+ apiScope := hiddenAPIStubsTag.apiScope
+ if hiddenAPIStubsTag.fromAdditionalDependency {
+ dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module, apiScope.sdkKind)
+ if dexJar != nil {
+ i.AdditionalStubDexJarsByScope[apiScope] = append(i.AdditionalStubDexJarsByScope[apiScope], dexJar)
+ }
+ } else {
+ addFromModule(ctx, module, apiScope)
+ }
}
})
// Normalize the paths, i.e. remove duplicates and sort.
- i.StubDexJarsByKind.dedupAndSort()
+ i.StubDexJarsByScope.dedupAndSort()
+ i.DependencyStubDexJarsByScope.dedupAndSort()
i.RemovedTxtFiles = android.SortedUniquePaths(i.RemovedTxtFiles)
}
@@ -546,9 +720,9 @@
}
}
-func (i *HiddenAPIFlagInput) transitiveStubDexJarsByKind() StubDexJarsByKind {
- transitive := i.DependencyStubDexJarsByKind
- transitive.append(i.StubDexJarsByKind)
+func (i *HiddenAPIFlagInput) transitiveStubDexJarsByScope() StubDexJarsByScope {
+ transitive := i.DependencyStubDexJarsByScope
+ transitive.append(i.StubDexJarsByScope)
return transitive
}
@@ -637,28 +811,6 @@
outputPath android.WritablePath, baseFlagsPath android.Path, annotationFlagPaths android.Paths,
flagFilesByCategory FlagFilesByCategory, allFlagsPaths android.Paths, generatedRemovedDexSignatures android.OptionalPath) {
- // The file which is used to record that the flags file is valid.
- var validFile android.WritablePath
-
- // If there are flag files that have been generated by fragments on which this depends then use
- // them to validate the flag file generated by the rules created by this method.
- if len(allFlagsPaths) > 0 {
- // The flags file generated by the rule created by this method needs to be validated to ensure
- // that it is consistent with the flag files generated by the individual fragments.
-
- validFile = pathForValidation(ctx, outputPath)
-
- // Create a rule to validate the output from the following rule.
- rule := android.NewRuleBuilder(pctx, ctx)
- rule.Command().
- BuiltTool("verify_overlaps").
- Input(outputPath).
- Inputs(allFlagsPaths).
- // If validation passes then update the file that records that.
- Text("&& touch").Output(validFile)
- rule.Build(name+"Validation", desc+" validation")
- }
-
// Create the rule that will generate the flag files.
tempPath := tempPathForRestat(ctx, outputPath)
rule := android.NewRuleBuilder(pctx, ctx)
@@ -684,7 +836,11 @@
commitChangeForRestat(rule, tempPath, outputPath)
- if validFile != nil {
+ // If there are flag files that have been generated by fragments on which this depends then use
+ // them to validate the flag file generated by the rules created by this method.
+ if len(allFlagsPaths) > 0 {
+ validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, allFlagsPaths)
+
// Add the file that indicates that the file generated by this is valid.
//
// This will cause the validation rule above to be run any time that the output of this rule
@@ -695,6 +851,25 @@
rule.Build(name, desc)
}
+// buildRuleValidateOverlappingCsvFiles checks that the modular CSV files, i.e. the files generated
+// by the individual bootclasspath_fragment modules are subsets of the monolithic CSV file.
+func buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name string, desc string, monolithicFilePath android.WritablePath, modularFilePaths android.Paths) android.WritablePath {
+ // The file which is used to record that the flags file is valid.
+ validFile := pathForValidation(ctx, monolithicFilePath)
+
+ // Create a rule to validate the output from the following rule.
+ rule := android.NewRuleBuilder(pctx, ctx)
+ rule.Command().
+ BuiltTool("verify_overlaps").
+ Input(monolithicFilePath).
+ Inputs(modularFilePaths).
+ // If validation passes then update the file that records that.
+ Text("&& touch").Output(validFile)
+ rule.Build(name+"Validation", desc+" validation")
+
+ return validFile
+}
+
// hiddenAPIRulesForBootclasspathFragment will generate all the flags for a fragment of the
// bootclasspath and then encode the flags into the boot dex files.
//
@@ -718,8 +893,7 @@
// Generate the stub-flags.csv.
stubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "stub-flags.csv")
- rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlagsCSV, bootDexInfoByModule.bootDexJars(), input)
- rule.Build("modularHiddenAPIStubFlagsFile", "modular hiddenapi stub flags")
+ buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "modularHiddenAPIStubFlagsFile", "modular hiddenapi stub flags", stubFlagsCSV, bootDexInfoByModule.bootDexJars(), input, nil)
// Extract the classes jars from the contents.
classesJars := extractClassesJarsFromModules(contents)
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index a444de0..d72cee0 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -119,8 +119,8 @@
}
// Add dependencies onto the stub lib modules.
- sdkKindToStubLibModules := hiddenAPIComputeMonolithicStubLibModules(ctx.Config())
- hiddenAPIAddStubLibDependencies(ctx, sdkKindToStubLibModules)
+ apiLevelToStubLibModules := hiddenAPIComputeMonolithicStubLibModules(ctx.Config())
+ hiddenAPIAddStubLibDependencies(ctx, apiLevelToStubLibModules)
}
func (b *platformBootclasspathModule) BootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
@@ -303,7 +303,7 @@
// the fragments will have already provided the flags that are needed.
classesJars := monolithicInfo.ClassesJars
- // Create the input to pass to ruleToGenerateHiddenAPIStubFlagsFile
+ // Create the input to pass to buildRuleToGenerateHiddenAPIStubFlagsFile
input := newHiddenAPIFlagInput()
// Gather stub library information from the dependencies on modules provided by
@@ -315,8 +315,7 @@
// Generate the monolithic stub-flags.csv file.
stubFlags := hiddenAPISingletonPaths(ctx).stubFlags
- rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlags, bootDexJarByModule.bootDexJars(), input)
- rule.Build("platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags")
+ buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags", stubFlags, bootDexJarByModule.bootDexJars(), input, monolithicInfo.StubFlagsPaths)
// Generate the annotation-flags.csv file from all the module annotations.
annotationFlags := android.PathForModuleOut(ctx, "hiddenapi-monolithic", "annotation-flags-from-classes.csv")
diff --git a/java/sdk_library.go b/java/sdk_library.go
index b07dcd1..567e292 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -684,6 +684,15 @@
return true
}
+// uniqueApexVariations provides common implementation of the ApexModule.UniqueApexVariations
+// method.
+func (c *commonToSdkLibraryAndImport) uniqueApexVariations() bool {
+ // A java_sdk_library that is a shared library produces an XML file that makes the shared library
+ // usable from an AndroidManifest.xml's <uses-library> entry. That XML file contains the name of
+ // the APEX and so it needs a unique variation per APEX.
+ return c.sharedLibrary()
+}
+
func (c *commonToSdkLibraryAndImport) generateCommonBuildActions(ctx android.ModuleContext) {
c.doctagPaths = android.PathsForModuleSrc(ctx, c.commonSdkLibraryProperties.Doctag_files)
}
@@ -1528,6 +1537,7 @@
mctx.CreateModule(DroidstubsFactory, &props)
}
+// Implements android.ApexModule
func (module *SdkLibrary) DepIsInSameApex(mctx android.BaseModuleContext, dep android.Module) bool {
depTag := mctx.OtherModuleDependencyTag(dep)
if depTag == xmlPermissionsFileTag {
@@ -1536,6 +1546,11 @@
return module.Library.DepIsInSameApex(mctx, dep)
}
+// Implements android.ApexModule
+func (module *SdkLibrary) UniqueApexVariations() bool {
+ return module.uniqueApexVariations()
+}
+
// Creates the xml file that publicizes the runtime library
func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) {
props := struct {
@@ -2090,6 +2105,11 @@
return nil
}
+// Implements android.ApexModule
+func (module *SdkLibraryImport) UniqueApexVariations() bool {
+ return module.uniqueApexVariations()
+}
+
func (module *SdkLibraryImport) OutputFiles(tag string) (android.Paths, error) {
return module.commonOutputFiles(tag)
}
diff --git a/scripts/OWNERS b/scripts/OWNERS
index 2b9c2de..1830a18 100644
--- a/scripts/OWNERS
+++ b/scripts/OWNERS
@@ -1,6 +1,6 @@
per-file system-clang-format,system-clang-format-2 = enh@google.com,smoreland@google.com
per-file build-mainline-modules.sh = ngeoffray@google.com,paulduffin@google.com,mast@google.com
per-file build-aml-prebuilts.sh = ngeoffray@google.com,paulduffin@google.com,mast@google.com
-per-file construct_context.py = ngeoffray@google.com,calin@google.com,mathieuc@google.com,skvadrik@google.com
+per-file construct_context.py = ngeoffray@google.com,calin@google.com,skvadrik@google.com
per-file conv_linker_config.py = kiyoungkim@google.com, jiyong@google.com, jooyung@google.com
per-file gen_ndk*.sh = sophiez@google.com, allenhair@google.com
diff --git a/scripts/hiddenapi/verify_overlaps.py b/scripts/hiddenapi/verify_overlaps.py
index c8e3879..bb0917e 100755
--- a/scripts/hiddenapi/verify_overlaps.py
+++ b/scripts/hiddenapi/verify_overlaps.py
@@ -47,9 +47,9 @@
if signature in allFlagsBySignature:
allFlags = allFlagsBySignature.get(signature)
if allFlags != row:
- mismatchingSignatures.append((signature, row[None], allFlags[None]))
+ mismatchingSignatures.append((signature, row.get(None, []), allFlags.get(None, [])))
else:
- mismatchingSignatures.append((signature, row[None], []))
+ mismatchingSignatures.append((signature, row.get(None, []), []))
if mismatchingSignatures:
@@ -60,7 +60,7 @@
for mismatch in mismatchingSignatures:
print()
print("< " + mismatch[0] + "," + ",".join(mismatch[1]))
- if mismatch[2] != None:
+ if mismatch[2] != []:
print("> " + mismatch[0] + "," + ",".join(mismatch[2]))
else:
print("> " + mismatch[0] + " - missing")
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index d47eb1f..a458cba 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -273,7 +273,7 @@
name: "myothersdklibrary",
apex_available: ["myapex"],
srcs: ["Test.java"],
- shared_library: false,
+ compile_dex: true,
public: {enabled: true},
min_sdk_version: "2",
permitted_packages: ["myothersdklibrary"],
@@ -283,7 +283,7 @@
name: "mycoreplatform",
apex_available: ["myapex"],
srcs: ["Test.java"],
- shared_library: false,
+ compile_dex: true,
public: {enabled: true},
min_sdk_version: "2",
}
@@ -334,7 +334,8 @@
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["myapex"],
- shared_library: false,
+ shared_library: true,
+ compile_dex: true,
public: {
jars: ["sdk_library/public/myothersdklibrary-stubs.jar"],
stub_srcs: ["sdk_library/public/myothersdklibrary_stub_sources"],
@@ -364,7 +365,8 @@
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["myapex"],
- shared_library: false,
+ shared_library: true,
+ compile_dex: true,
public: {
jars: ["sdk_library/public/mycoreplatform-stubs.jar"],
stub_srcs: ["sdk_library/public/mycoreplatform_stub_sources"],
@@ -414,7 +416,8 @@
sdk_member_name: "myothersdklibrary",
visibility: ["//visibility:public"],
apex_available: ["myapex"],
- shared_library: false,
+ shared_library: true,
+ compile_dex: true,
public: {
jars: ["sdk_library/public/myothersdklibrary-stubs.jar"],
stub_srcs: ["sdk_library/public/myothersdklibrary_stub_sources"],
@@ -444,7 +447,8 @@
sdk_member_name: "mycoreplatform",
visibility: ["//visibility:public"],
apex_available: ["myapex"],
- shared_library: false,
+ shared_library: true,
+ compile_dex: true,
public: {
jars: ["sdk_library/public/mycoreplatform-stubs.jar"],
stub_srcs: ["sdk_library/public/mycoreplatform_stub_sources"],
diff --git a/sdk/update.go b/sdk/update.go
index 3f61339..b146b62 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -156,6 +156,11 @@
if memberTag, ok := tag.(android.SdkMemberTypeDependencyTag); ok {
memberType := memberTag.SdkMemberType(child)
+ // If a nil SdkMemberType was returned then this module should not be added to the sdk.
+ if memberType == nil {
+ return false
+ }
+
// Make sure that the resolved module is allowed in the member list property.
if !memberType.IsInstance(child) {
ctx.ModuleErrorf("module %q is not valid in property %s", ctx.OtherModuleName(child), memberType.SdkPropertyName())
diff --git a/ui/build/build.go b/ui/build/build.go
index 8f050d9..1187aa2 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -274,6 +274,11 @@
// Return early, if we're using Soong as solely the generator of BUILD files.
return
}
+
+ if config.bazelBuildMode() == generateJsonModuleGraph {
+ // Return early, if we're using Soong as solely the generator of the JSON module graph
+ return
+ }
}
if what&RunKati != 0 {
diff --git a/ui/build/config.go b/ui/build/config.go
index b9aaaf8..4806721 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -108,6 +108,9 @@
// Only generate build files (in a subdirectory of the out directory) and exit.
generateBuildFiles
+ // Only generate the Soong json module graph for use with jq, and exit.
+ generateJsonModuleGraph
+
// Generate synthetic build files and incorporate these files into a build which
// partially uses Bazel. Build metadata may come from Android.bp or BUILD files.
mixedBuild
@@ -936,6 +939,8 @@
return mixedBuild
} else if c.Environment().IsEnvTrue("GENERATE_BAZEL_FILES") {
return generateBuildFiles
+ } else if v, ok := c.Environment().Get("SOONG_DUMP_JSON_MODULE_GRAPH"); ok && v != "" {
+ return generateJsonModuleGraph
} else {
return noBazel
}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 19a47ae..a40457f 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -333,8 +333,9 @@
}
func shouldCollectBuildSoongMetrics(config Config) bool {
- // Do not collect metrics protobuf if the soong_build binary ran as the bp2build converter.
- return config.bazelBuildMode() != generateBuildFiles
+ // Do not collect metrics protobuf if the soong_build binary ran as the
+ // bp2build converter or the JSON graph dump.
+ return config.bazelBuildMode() != generateBuildFiles && config.bazelBuildMode() != generateJsonModuleGraph
}
func loadSoongBuildMetrics(ctx Context, config Config) *soong_metrics_proto.SoongBuildMetrics {