Support hidden API processing for modules that use platform APIs
Previously, hidden API processing could only be done by those bootclasspath_fragment modules that either did not depend on any other fragments (e.g. art-bootclasspath-fragment) or only depended on APIs provided by other fragments (e.g. i18n-bootclasspath-fragment). That meant that modules like com.android.os.statsd-bootclasspath-fragment that depended on APIs provided by parts of the platform which are not yet part of another bootclasspath_fragment could not perform hidden API processing. This change adds support for a bootclasspath_fragment to specify the additional stubs needed to perform hidden API processing. It adds a new additional_stubs property that can be used to specify the additional stub libraries. Most bootclasspath_fragments that need to use the property will need access to the APIs provided by the android-non-updatable.* libraries. Rather than have each fragment explicitly specify the correct module for each scope it treats "android-non-updatable" as if it was a java_sdk_library that can provide different jars for each scope. Soong will handle mapping that to the correct android-non-updatable.* module. Bug: 179354495 Test: m out/soong/hiddenapi/hiddenapi-flags.csv \ out/soong/hiddenapi/hiddenapi-index.csv \ out/soong/hiddenapi/hiddenapi-stub-flags.txt \ out/soong/hiddenapi/hiddenapi-unsupported.csv - make sure that this change does not change the contents. m TARGET_BUILD_APPS=Calendar nothing Change-Id: Ia8b79830ed0e6d42100de03d76b0c51b7f6c8ade
This commit is contained in:
parent
136fd5554d
commit
5cca7c44e5
5 changed files with 451 additions and 12 deletions
|
@ -375,6 +375,8 @@ type SdkMemberTypeDependencyTag interface {
|
|||
|
||||
// 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
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
"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
|
||||
|
@ -868,4 +869,330 @@ func TestBootclasspathFragment_HiddenAPIList(t *testing.T) {
|
|||
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.
|
||||
|
|
|
@ -124,6 +124,15 @@ type bootclasspathFragmentProperties struct {
|
|||
// 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.
|
||||
|
@ -381,6 +390,15 @@ func (b *BootclasspathFragmentModule) DepsMutator(ctx android.BottomUpMutatorCon
|
|||
// bootclasspath fragment.
|
||||
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
|
||||
}
|
||||
|
@ -640,8 +658,8 @@ func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.Modul
|
|||
// 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.DependencyStubDexJarsByScope = dependencyHiddenApiInfo.TransitiveStubDexJarsByScope
|
||||
// Add the stub dex jars from this module's fragment dependencies.
|
||||
input.DependencyStubDexJarsByScope.append(dependencyHiddenApiInfo.TransitiveStubDexJarsByScope)
|
||||
|
||||
return input
|
||||
}
|
||||
|
|
|
@ -37,13 +37,65 @@ type HiddenAPIScope struct {
|
|||
|
||||
// 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)
|
||||
}
|
||||
|
@ -122,6 +174,11 @@ type hiddenAPIStubsDependencyTag struct {
|
|||
|
||||
// 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() {
|
||||
|
@ -132,6 +189,11 @@ func (b hiddenAPIStubsDependencyTag) ReplaceSourceWithPrebuilt() bool {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -243,15 +305,10 @@ func ruleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, outputPath
|
|||
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(hiddenAPIScopes) - 1; i >= 0; i-- {
|
||||
apiScope := hiddenAPIScopes[i]
|
||||
stubsForAPIScope := input.DependencyStubDexJarsByScope[apiScope]
|
||||
if len(stubsForAPIScope) != 0 {
|
||||
dependencyStubDexJars = stubsForAPIScope
|
||||
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")).
|
||||
|
@ -266,6 +323,7 @@ func ruleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, outputPath
|
|||
// 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 := apiScope.hiddenAPIListOption
|
||||
|
@ -501,6 +559,20 @@ func (s StubDexJarsByScope) dedupAndSort() {
|
|||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
|
@ -517,6 +589,13 @@ type HiddenAPIFlagInput struct {
|
|||
// fragment on which this depends.
|
||||
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.
|
||||
RemovedTxtFiles android.Paths
|
||||
|
@ -528,6 +607,7 @@ func newHiddenAPIFlagInput() HiddenAPIFlagInput {
|
|||
FlagFilesByCategory: FlagFilesByCategory{},
|
||||
StubDexJarsByScope: StubDexJarsByScope{},
|
||||
DependencyStubDexJarsByScope: StubDexJarsByScope{},
|
||||
AdditionalStubDexJarsByScope: StubDexJarsByScope{},
|
||||
}
|
||||
|
||||
return input
|
||||
|
@ -601,7 +681,14 @@ func (i *HiddenAPIFlagInput) gatherStubLibInfo(ctx android.ModuleContext, conten
|
|||
tag := ctx.OtherModuleDependencyTag(module)
|
||||
if hiddenAPIStubsTag, ok := tag.(hiddenAPIStubsDependencyTag); ok {
|
||||
apiScope := hiddenAPIStubsTag.apiScope
|
||||
addFromModule(ctx, module, 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)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -156,6 +156,11 @@ func (s *sdk) collectMembers(ctx android.ModuleContext) {
|
|||
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())
|
||||
|
|
Loading…
Reference in a new issue