Remove exportable modules when generating snapshots targeting older platform
This change modifies the contents of the generated Android.bp files so that when generating a snapshot on a older platform, the "exportable" modules are removed from the bp files, as the "exportable" modules are first introduced in V and do not exist in older platforms. Bug: 345162614 Test: ABTD Change-Id: I2dba51b98deec7805bd796647a66981f237c55a9
This commit is contained in:
parent
d5e16ac52b
commit
98aa8fa840
5 changed files with 209 additions and 11 deletions
|
@ -291,6 +291,8 @@ var ApiLevelR = uncheckedFinalApiLevel(30)
|
||||||
|
|
||||||
var ApiLevelUpsideDownCake = uncheckedFinalApiLevel(34)
|
var ApiLevelUpsideDownCake = uncheckedFinalApiLevel(34)
|
||||||
|
|
||||||
|
var ApiLevelVanillaIceCream = uncheckedFinalApiLevel(35)
|
||||||
|
|
||||||
// ReplaceFinalizedCodenames returns the API level number associated with that API level
|
// ReplaceFinalizedCodenames returns the API level number associated with that API level
|
||||||
// if the `raw` input is the codename of an API level has been finalized.
|
// if the `raw` input is the codename of an API level has been finalized.
|
||||||
// If the input is *not* a finalized codename, the input is returned unmodified.
|
// If the input is *not* a finalized codename, the input is returned unmodified.
|
||||||
|
|
|
@ -2178,7 +2178,7 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||||
|
|
||||||
// Map where key is the api scope name and value is the int value
|
// Map where key is the api scope name and value is the int value
|
||||||
// representing the order of the api scope, narrowest to the widest
|
// representing the order of the api scope, narrowest to the widest
|
||||||
var scopeOrderMap = allApiScopes.MapToIndex(
|
var scopeOrderMap = AllApiScopes.MapToIndex(
|
||||||
func(s *apiScope) string { return s.name })
|
func(s *apiScope) string { return s.name })
|
||||||
|
|
||||||
func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo) []JavaApiImportInfo {
|
func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo) []JavaApiImportInfo {
|
||||||
|
|
|
@ -324,6 +324,16 @@ func (scopes apiScopes) MapToIndex(accessor func(*apiScope) string) map[string]i
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (scopes apiScopes) ConvertStubsLibraryExportableToEverything(name string) string {
|
||||||
|
for _, scope := range scopes {
|
||||||
|
if strings.HasSuffix(name, scope.exportableStubsLibraryModuleNameSuffix()) {
|
||||||
|
return strings.TrimSuffix(name, scope.exportableStubsLibraryModuleNameSuffix()) +
|
||||||
|
scope.stubsLibraryModuleNameSuffix()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
scopeByName = make(map[string]*apiScope)
|
scopeByName = make(map[string]*apiScope)
|
||||||
allScopeNames []string
|
allScopeNames []string
|
||||||
|
@ -418,7 +428,7 @@ var (
|
||||||
},
|
},
|
||||||
kind: android.SdkSystemServer,
|
kind: android.SdkSystemServer,
|
||||||
})
|
})
|
||||||
allApiScopes = apiScopes{
|
AllApiScopes = apiScopes{
|
||||||
apiScopePublic,
|
apiScopePublic,
|
||||||
apiScopeSystem,
|
apiScopeSystem,
|
||||||
apiScopeTest,
|
apiScopeTest,
|
||||||
|
@ -1204,7 +1214,7 @@ func (c *commonToSdkLibraryAndImport) selectScopePaths(ctx android.BaseModuleCon
|
||||||
paths := c.findClosestScopePath(apiScope)
|
paths := c.findClosestScopePath(apiScope)
|
||||||
if paths == nil {
|
if paths == nil {
|
||||||
var scopes []string
|
var scopes []string
|
||||||
for _, s := range allApiScopes {
|
for _, s := range AllApiScopes {
|
||||||
if c.findScopePaths(s) != nil {
|
if c.findScopePaths(s) != nil {
|
||||||
scopes = append(scopes, s.name)
|
scopes = append(scopes, s.name)
|
||||||
}
|
}
|
||||||
|
@ -1421,7 +1431,7 @@ func (module *SdkLibrary) getGeneratedApiScopes(ctx android.EarlyModuleContext)
|
||||||
// Check to see if any scopes have been explicitly enabled. If any have then all
|
// Check to see if any scopes have been explicitly enabled. If any have then all
|
||||||
// must be.
|
// must be.
|
||||||
anyScopesExplicitlyEnabled := false
|
anyScopesExplicitlyEnabled := false
|
||||||
for _, scope := range allApiScopes {
|
for _, scope := range AllApiScopes {
|
||||||
scopeProperties := module.scopeToProperties[scope]
|
scopeProperties := module.scopeToProperties[scope]
|
||||||
if scopeProperties.Enabled != nil {
|
if scopeProperties.Enabled != nil {
|
||||||
anyScopesExplicitlyEnabled = true
|
anyScopesExplicitlyEnabled = true
|
||||||
|
@ -1431,7 +1441,7 @@ func (module *SdkLibrary) getGeneratedApiScopes(ctx android.EarlyModuleContext)
|
||||||
|
|
||||||
var generatedScopes apiScopes
|
var generatedScopes apiScopes
|
||||||
enabledScopes := make(map[*apiScope]struct{})
|
enabledScopes := make(map[*apiScope]struct{})
|
||||||
for _, scope := range allApiScopes {
|
for _, scope := range AllApiScopes {
|
||||||
scopeProperties := module.scopeToProperties[scope]
|
scopeProperties := module.scopeToProperties[scope]
|
||||||
// If any scopes are explicitly enabled then ignore the legacy enabled status.
|
// If any scopes are explicitly enabled then ignore the legacy enabled status.
|
||||||
// This is to ensure that any new usages of this module type do not rely on legacy
|
// This is to ensure that any new usages of this module type do not rely on legacy
|
||||||
|
@ -1451,7 +1461,7 @@ func (module *SdkLibrary) getGeneratedApiScopes(ctx android.EarlyModuleContext)
|
||||||
|
|
||||||
// Now check to make sure that any scope that is extended by an enabled scope is also
|
// Now check to make sure that any scope that is extended by an enabled scope is also
|
||||||
// enabled.
|
// enabled.
|
||||||
for _, scope := range allApiScopes {
|
for _, scope := range AllApiScopes {
|
||||||
if _, ok := enabledScopes[scope]; ok {
|
if _, ok := enabledScopes[scope]; ok {
|
||||||
extends := scope.extends
|
extends := scope.extends
|
||||||
if extends != nil {
|
if extends != nil {
|
||||||
|
@ -2580,7 +2590,7 @@ func SdkLibraryFactory() android.Module {
|
||||||
|
|
||||||
// Initialize the map from scope to scope specific properties.
|
// Initialize the map from scope to scope specific properties.
|
||||||
scopeToProperties := make(map[*apiScope]*ApiScopeProperties)
|
scopeToProperties := make(map[*apiScope]*ApiScopeProperties)
|
||||||
for _, scope := range allApiScopes {
|
for _, scope := range AllApiScopes {
|
||||||
scopeToProperties[scope] = scope.scopeSpecificProperties(module)
|
scopeToProperties[scope] = scope.scopeSpecificProperties(module)
|
||||||
}
|
}
|
||||||
module.scopeToProperties = scopeToProperties
|
module.scopeToProperties = scopeToProperties
|
||||||
|
@ -2697,7 +2707,7 @@ var allScopeStructType = createAllScopePropertiesStructType()
|
||||||
// Dynamically create a structure type for each apiscope in allApiScopes.
|
// Dynamically create a structure type for each apiscope in allApiScopes.
|
||||||
func createAllScopePropertiesStructType() reflect.Type {
|
func createAllScopePropertiesStructType() reflect.Type {
|
||||||
var fields []reflect.StructField
|
var fields []reflect.StructField
|
||||||
for _, apiScope := range allApiScopes {
|
for _, apiScope := range AllApiScopes {
|
||||||
field := reflect.StructField{
|
field := reflect.StructField{
|
||||||
Name: apiScope.fieldName,
|
Name: apiScope.fieldName,
|
||||||
Type: reflect.TypeOf(sdkLibraryScopeProperties{}),
|
Type: reflect.TypeOf(sdkLibraryScopeProperties{}),
|
||||||
|
@ -2715,7 +2725,7 @@ func createPropertiesInstance() (interface{}, map[*apiScope]*sdkLibraryScopeProp
|
||||||
allScopePropertiesStruct := allScopePropertiesPtr.Elem()
|
allScopePropertiesStruct := allScopePropertiesPtr.Elem()
|
||||||
scopeProperties := make(map[*apiScope]*sdkLibraryScopeProperties)
|
scopeProperties := make(map[*apiScope]*sdkLibraryScopeProperties)
|
||||||
|
|
||||||
for _, apiScope := range allApiScopes {
|
for _, apiScope := range AllApiScopes {
|
||||||
field := allScopePropertiesStruct.FieldByName(apiScope.fieldName)
|
field := allScopePropertiesStruct.FieldByName(apiScope.fieldName)
|
||||||
scopeProperties[apiScope] = field.Addr().Interface().(*sdkLibraryScopeProperties)
|
scopeProperties[apiScope] = field.Addr().Interface().(*sdkLibraryScopeProperties)
|
||||||
}
|
}
|
||||||
|
@ -3597,7 +3607,7 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe
|
||||||
s.Stem = sdk.distStem()
|
s.Stem = sdk.distStem()
|
||||||
|
|
||||||
s.Scopes = make(map[*apiScope]*scopeProperties)
|
s.Scopes = make(map[*apiScope]*scopeProperties)
|
||||||
for _, apiScope := range allApiScopes {
|
for _, apiScope := range AllApiScopes {
|
||||||
paths := sdk.findScopePaths(apiScope)
|
paths := sdk.findScopePaths(apiScope)
|
||||||
if paths == nil {
|
if paths == nil {
|
||||||
continue
|
continue
|
||||||
|
@ -3659,7 +3669,7 @@ func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberCo
|
||||||
|
|
||||||
stem := s.Stem
|
stem := s.Stem
|
||||||
|
|
||||||
for _, apiScope := range allApiScopes {
|
for _, apiScope := range AllApiScopes {
|
||||||
if properties, ok := s.Scopes[apiScope]; ok {
|
if properties, ok := s.Scopes[apiScope]; ok {
|
||||||
scopeSet := propertySet.AddPropertySet(apiScope.propertyName)
|
scopeSet := propertySet.AddPropertySet(apiScope.propertyName)
|
||||||
|
|
||||||
|
|
136
sdk/sdk_test.go
136
sdk/sdk_test.go
|
@ -515,6 +515,142 @@ java_sdk_library_import {
|
||||||
.intermediates/mysdklibrary.stubs.exportable/android_common/combined/mysdklibrary.stubs.exportable.jar -> sdk_library/public/mysdklibrary-stubs.jar
|
.intermediates/mysdklibrary.stubs.exportable/android_common/combined/mysdklibrary.stubs.exportable.jar -> sdk_library/public/mysdklibrary-stubs.jar
|
||||||
.intermediates/mysdklibrary.stubs.source/android_common/exportable/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt
|
.intermediates/mysdklibrary.stubs.source/android_common/exportable/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt
|
||||||
.intermediates/mysdklibrary.stubs.source/android_common/exportable/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt
|
.intermediates/mysdklibrary.stubs.source/android_common/exportable/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt
|
||||||
|
`),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test replacing exportable module", func(t *testing.T) {
|
||||||
|
result := android.GroupFixturePreparers(
|
||||||
|
prepareForSdkTestWithJava,
|
||||||
|
java.PrepareForTestWithJavaDefaultModules,
|
||||||
|
java.PrepareForTestWithJavaSdkLibraryFiles,
|
||||||
|
java.FixtureWithLastReleaseApis("mysdklibrary", "anothersdklibrary"),
|
||||||
|
android.FixtureWithRootAndroidBp(`
|
||||||
|
sdk {
|
||||||
|
name: "mysdk",
|
||||||
|
bootclasspath_fragments: ["mybootclasspathfragment"],
|
||||||
|
}
|
||||||
|
|
||||||
|
bootclasspath_fragment {
|
||||||
|
name: "mybootclasspathfragment",
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
contents: ["mysdklibrary"],
|
||||||
|
hidden_api: {
|
||||||
|
split_packages: ["*"],
|
||||||
|
},
|
||||||
|
core_platform_api: {
|
||||||
|
stub_libs: [
|
||||||
|
"anothersdklibrary.stubs.exportable",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
api: {
|
||||||
|
stub_libs: [
|
||||||
|
"anothersdklibrary",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
java_sdk_library {
|
||||||
|
name: "mysdklibrary",
|
||||||
|
srcs: ["Test.java"],
|
||||||
|
compile_dex: true,
|
||||||
|
min_sdk_version: "S",
|
||||||
|
public: {enabled: true},
|
||||||
|
permitted_packages: ["mysdklibrary"],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_sdk_library {
|
||||||
|
name: "anothersdklibrary",
|
||||||
|
srcs: ["Test.java"],
|
||||||
|
compile_dex: true,
|
||||||
|
min_sdk_version: "S",
|
||||||
|
public: {enabled: true},
|
||||||
|
system: {enabled: true},
|
||||||
|
module_lib: {enabled: true},
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
android.FixtureMergeEnv(map[string]string{
|
||||||
|
"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": "S",
|
||||||
|
}),
|
||||||
|
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
|
||||||
|
variables.BuildFlags = map[string]string{
|
||||||
|
"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
|
||||||
|
}
|
||||||
|
variables.Platform_version_active_codenames = []string{"UpsideDownCake", "Tiramisu", "S-V2"}
|
||||||
|
}),
|
||||||
|
).RunTest(t)
|
||||||
|
|
||||||
|
CheckSnapshot(t, result, "mysdk", "",
|
||||||
|
checkAndroidBpContents(`
|
||||||
|
// This is auto-generated. DO NOT EDIT.
|
||||||
|
|
||||||
|
prebuilt_bootclasspath_fragment {
|
||||||
|
name: "mybootclasspathfragment",
|
||||||
|
prefer: false,
|
||||||
|
visibility: ["//visibility:public"],
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
contents: ["mysdklibrary"],
|
||||||
|
api: {
|
||||||
|
stub_libs: ["anothersdklibrary"],
|
||||||
|
},
|
||||||
|
core_platform_api: {
|
||||||
|
stub_libs: ["anothersdklibrary.stubs"],
|
||||||
|
},
|
||||||
|
hidden_api: {
|
||||||
|
annotation_flags: "hiddenapi/annotation-flags.csv",
|
||||||
|
metadata: "hiddenapi/metadata.csv",
|
||||||
|
index: "hiddenapi/index.csv",
|
||||||
|
stub_flags: "hiddenapi/stub-flags.csv",
|
||||||
|
all_flags: "hiddenapi/all-flags.csv",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
java_sdk_library_import {
|
||||||
|
name: "mysdklibrary",
|
||||||
|
prefer: false,
|
||||||
|
visibility: ["//visibility:public"],
|
||||||
|
apex_available: ["//apex_available:platform"],
|
||||||
|
shared_library: true,
|
||||||
|
compile_dex: true,
|
||||||
|
permitted_packages: ["mysdklibrary"],
|
||||||
|
public: {
|
||||||
|
jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
|
||||||
|
stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
|
||||||
|
current_api: "sdk_library/public/mysdklibrary.txt",
|
||||||
|
removed_api: "sdk_library/public/mysdklibrary-removed.txt",
|
||||||
|
sdk_version: "current",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
java_sdk_library_import {
|
||||||
|
name: "anothersdklibrary",
|
||||||
|
prefer: false,
|
||||||
|
visibility: ["//visibility:public"],
|
||||||
|
apex_available: ["//apex_available:platform"],
|
||||||
|
shared_library: true,
|
||||||
|
compile_dex: true,
|
||||||
|
public: {
|
||||||
|
jars: ["sdk_library/public/anothersdklibrary-stubs.jar"],
|
||||||
|
stub_srcs: ["sdk_library/public/anothersdklibrary_stub_sources"],
|
||||||
|
current_api: "sdk_library/public/anothersdklibrary.txt",
|
||||||
|
removed_api: "sdk_library/public/anothersdklibrary-removed.txt",
|
||||||
|
sdk_version: "current",
|
||||||
|
},
|
||||||
|
system: {
|
||||||
|
jars: ["sdk_library/system/anothersdklibrary-stubs.jar"],
|
||||||
|
stub_srcs: ["sdk_library/system/anothersdklibrary_stub_sources"],
|
||||||
|
current_api: "sdk_library/system/anothersdklibrary.txt",
|
||||||
|
removed_api: "sdk_library/system/anothersdklibrary-removed.txt",
|
||||||
|
sdk_version: "system_current",
|
||||||
|
},
|
||||||
|
module_lib: {
|
||||||
|
jars: ["sdk_library/module-lib/anothersdklibrary-stubs.jar"],
|
||||||
|
stub_srcs: ["sdk_library/module-lib/anothersdklibrary_stub_sources"],
|
||||||
|
current_api: "sdk_library/module-lib/anothersdklibrary.txt",
|
||||||
|
removed_api: "sdk_library/module-lib/anothersdklibrary-removed.txt",
|
||||||
|
sdk_version: "module_current",
|
||||||
|
},
|
||||||
|
}
|
||||||
`),
|
`),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -480,6 +480,12 @@ be unnecessary as every module in the sdk already has its own licenses property.
|
||||||
// Transform the module module to make it suitable for use in the snapshot.
|
// Transform the module module to make it suitable for use in the snapshot.
|
||||||
module = transformModule(module, snapshotTransformer)
|
module = transformModule(module, snapshotTransformer)
|
||||||
module = transformModule(module, emptyClasspathContentsTransformation{})
|
module = transformModule(module, emptyClasspathContentsTransformation{})
|
||||||
|
|
||||||
|
targetApiLevel, err := android.ApiLevelFromUserWithConfig(ctx.Config(), s.targetBuildRelease(ctx).name)
|
||||||
|
if err == nil && targetApiLevel.LessThan(android.ApiLevelVanillaIceCream) {
|
||||||
|
module = transformModule(module, replaceExportablePropertiesTransformer{})
|
||||||
|
}
|
||||||
|
|
||||||
if module != nil {
|
if module != nil {
|
||||||
bpFile.AddModule(module)
|
bpFile.AddModule(module)
|
||||||
}
|
}
|
||||||
|
@ -804,6 +810,50 @@ func (t pruneEmptySetTransformer) transformPropertySetAfterContents(_ string, pr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type replaceExportablePropertiesTransformer struct {
|
||||||
|
identityTransformation
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ bpTransformer = (*replaceExportablePropertiesTransformer)(nil)
|
||||||
|
|
||||||
|
func handleExportableProperties[T any](value T) any {
|
||||||
|
switch v := any(value).(type) {
|
||||||
|
case string:
|
||||||
|
return java.AllApiScopes.ConvertStubsLibraryExportableToEverything(v)
|
||||||
|
case *bpPropertySet:
|
||||||
|
v.properties = handleExportableProperties(v.properties).(map[string]interface{})
|
||||||
|
return v
|
||||||
|
case []string:
|
||||||
|
result := make([]string, len(v))
|
||||||
|
for i, elem := range v {
|
||||||
|
result[i] = handleExportableProperties(elem).(string)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
case []any:
|
||||||
|
result := make([]any, len(v))
|
||||||
|
for i, elem := range v {
|
||||||
|
result[i] = handleExportableProperties(elem)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
case map[string]any:
|
||||||
|
result := make(map[string]any)
|
||||||
|
for k, val := range v {
|
||||||
|
result[k] = handleExportableProperties(val)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
default:
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t replaceExportablePropertiesTransformer) transformPropertySetAfterContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
|
||||||
|
if name == "name" {
|
||||||
|
return propertySet, tag
|
||||||
|
}
|
||||||
|
propertySet.properties = handleExportableProperties(propertySet.properties).(map[string]interface{})
|
||||||
|
return propertySet, tag
|
||||||
|
}
|
||||||
|
|
||||||
func generateBpContents(bpFile *bpFile) string {
|
func generateBpContents(bpFile *bpFile) string {
|
||||||
contents := &generatedContents{}
|
contents := &generatedContents{}
|
||||||
contents.IndentedPrintf("// This is auto-generated. DO NOT EDIT.\n")
|
contents.IndentedPrintf("// This is auto-generated. DO NOT EDIT.\n")
|
||||||
|
|
Loading…
Reference in a new issue