Merge "Support hidden API processing for modules that use platform APIs"
This commit is contained in:
@@ -375,6 +375,8 @@ type SdkMemberTypeDependencyTag interface {
|
|||||||
|
|
||||||
// SdkMemberType returns the SdkMemberType that will be used to automatically add the child module
|
// SdkMemberType returns the SdkMemberType that will be used to automatically add the child module
|
||||||
// to the sdk.
|
// to the sdk.
|
||||||
|
//
|
||||||
|
// Returning nil will prevent the module being added to the sdk.
|
||||||
SdkMemberType(child Module) SdkMemberType
|
SdkMemberType(child Module) SdkMemberType
|
||||||
|
|
||||||
// ExportMember determines whether a module added to the sdk through this tag will be exported
|
// 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/android"
|
||||||
"android/soong/java"
|
"android/soong/java"
|
||||||
|
"github.com/google/blueprint/proptools"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Contains tests for bootclasspath_fragment logic from java/bootclasspath_fragment.go as the ART
|
// 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)
|
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.
|
// TODO(b/177892522) - add test for host apex.
|
||||||
|
@@ -124,6 +124,15 @@ type bootclasspathFragmentProperties struct {
|
|||||||
// Hidden API related properties.
|
// Hidden API related properties.
|
||||||
Hidden_api HiddenAPIFlagFileProperties
|
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
|
// 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
|
// processing as it needs access to all the classes used by a fragment including those provided
|
||||||
// by other fragments.
|
// by other fragments.
|
||||||
@@ -381,6 +390,15 @@ func (b *BootclasspathFragmentModule) DepsMutator(ctx android.BottomUpMutatorCon
|
|||||||
// bootclasspath fragment.
|
// bootclasspath fragment.
|
||||||
hiddenAPIAddStubLibDependencies(ctx, b.properties.apiScopeToStubLibs())
|
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) {
|
if SkipDexpreoptBootJars(ctx) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -640,8 +658,8 @@ func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.Modul
|
|||||||
// Populate with flag file paths from the properties.
|
// Populate with flag file paths from the properties.
|
||||||
input.extractFlagFilesFromProperties(ctx, &b.properties.Hidden_api)
|
input.extractFlagFilesFromProperties(ctx, &b.properties.Hidden_api)
|
||||||
|
|
||||||
// Store the stub dex jars from this module's fragment dependencies.
|
// Add the stub dex jars from this module's fragment dependencies.
|
||||||
input.DependencyStubDexJarsByScope = dependencyHiddenApiInfo.TransitiveStubDexJarsByScope
|
input.DependencyStubDexJarsByScope.append(dependencyHiddenApiInfo.TransitiveStubDexJarsByScope)
|
||||||
|
|
||||||
return input
|
return input
|
||||||
}
|
}
|
||||||
|
@@ -37,13 +37,65 @@ type HiddenAPIScope struct {
|
|||||||
|
|
||||||
// The option needed to passed to "hiddenapi list".
|
// The option needed to passed to "hiddenapi list".
|
||||||
hiddenAPIListOption string
|
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.
|
// initHiddenAPIScope initializes the scope.
|
||||||
func initHiddenAPIScope(apiScope *HiddenAPIScope) *HiddenAPIScope {
|
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
|
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 {
|
func (l *HiddenAPIScope) String() string {
|
||||||
return fmt.Sprintf("HiddenAPIScope{%s}", l.name)
|
return fmt.Sprintf("HiddenAPIScope{%s}", l.name)
|
||||||
}
|
}
|
||||||
@@ -122,6 +174,11 @@ type hiddenAPIStubsDependencyTag struct {
|
|||||||
|
|
||||||
// The api scope for which this dependency was added.
|
// The api scope for which this dependency was added.
|
||||||
apiScope *HiddenAPIScope
|
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() {
|
func (b hiddenAPIStubsDependencyTag) ExcludeFromApexContents() {
|
||||||
@@ -132,6 +189,11 @@ func (b hiddenAPIStubsDependencyTag) ReplaceSourceWithPrebuilt() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b hiddenAPIStubsDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType {
|
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
|
// 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.
|
// property, otherwise treat if it was specified in the java_header_libs property.
|
||||||
if javaSdkLibrarySdkMemberType.IsInstance(child) {
|
if javaSdkLibrarySdkMemberType.IsInstance(child) {
|
||||||
@@ -243,15 +305,10 @@ func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name,
|
|||||||
tempPath := tempPathForRestat(ctx, outputPath)
|
tempPath := tempPathForRestat(ctx, outputPath)
|
||||||
|
|
||||||
// Find the widest API stubs provided by the fragments on which this depends, if any.
|
// Find the widest API stubs provided by the fragments on which this depends, if any.
|
||||||
var dependencyStubDexJars android.Paths
|
dependencyStubDexJars := input.DependencyStubDexJarsByScope.stubDexJarsForWidestAPIScope()
|
||||||
for i := len(hiddenAPIScopes) - 1; i >= 0; i-- {
|
|
||||||
apiScope := hiddenAPIScopes[i]
|
// Add widest API stubs from the additional dependencies of this, if any.
|
||||||
stubsForAPIScope := input.DependencyStubDexJarsByScope[apiScope]
|
dependencyStubDexJars = append(dependencyStubDexJars, input.AdditionalStubDexJarsByScope.stubDexJarsForWidestAPIScope()...)
|
||||||
if len(stubsForAPIScope) != 0 {
|
|
||||||
dependencyStubDexJars = stubsForAPIScope
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
command := rule.Command().
|
command := rule.Command().
|
||||||
Tool(ctx.Config().HostToolPath(ctx, "hiddenapi")).
|
Tool(ctx.Config().HostToolPath(ctx, "hiddenapi")).
|
||||||
@@ -266,6 +323,7 @@ func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name,
|
|||||||
// other fragment's APIs.
|
// other fragment's APIs.
|
||||||
var paths android.Paths
|
var paths android.Paths
|
||||||
paths = append(paths, input.DependencyStubDexJarsByScope[apiScope]...)
|
paths = append(paths, input.DependencyStubDexJarsByScope[apiScope]...)
|
||||||
|
paths = append(paths, input.AdditionalStubDexJarsByScope[apiScope]...)
|
||||||
paths = append(paths, input.StubDexJarsByScope[apiScope]...)
|
paths = append(paths, input.StubDexJarsByScope[apiScope]...)
|
||||||
if len(paths) > 0 {
|
if len(paths) > 0 {
|
||||||
option := apiScope.hiddenAPIListOption
|
option := apiScope.hiddenAPIListOption
|
||||||
@@ -514,6 +572,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
|
// HiddenAPIFlagInput encapsulates information obtained from a module and its dependencies that are
|
||||||
// needed for hidden API flag generation.
|
// needed for hidden API flag generation.
|
||||||
type HiddenAPIFlagInput struct {
|
type HiddenAPIFlagInput struct {
|
||||||
@@ -530,6 +602,13 @@ type HiddenAPIFlagInput struct {
|
|||||||
// fragment on which this depends.
|
// fragment on which this depends.
|
||||||
DependencyStubDexJarsByScope StubDexJarsByScope
|
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
|
// 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.
|
// specified in the bootclasspath_fragment's stub_libs and contents properties.
|
||||||
RemovedTxtFiles android.Paths
|
RemovedTxtFiles android.Paths
|
||||||
@@ -541,6 +620,7 @@ func newHiddenAPIFlagInput() HiddenAPIFlagInput {
|
|||||||
FlagFilesByCategory: FlagFilesByCategory{},
|
FlagFilesByCategory: FlagFilesByCategory{},
|
||||||
StubDexJarsByScope: StubDexJarsByScope{},
|
StubDexJarsByScope: StubDexJarsByScope{},
|
||||||
DependencyStubDexJarsByScope: StubDexJarsByScope{},
|
DependencyStubDexJarsByScope: StubDexJarsByScope{},
|
||||||
|
AdditionalStubDexJarsByScope: StubDexJarsByScope{},
|
||||||
}
|
}
|
||||||
|
|
||||||
return input
|
return input
|
||||||
@@ -614,7 +694,14 @@ func (i *HiddenAPIFlagInput) gatherStubLibInfo(ctx android.ModuleContext, conten
|
|||||||
tag := ctx.OtherModuleDependencyTag(module)
|
tag := ctx.OtherModuleDependencyTag(module)
|
||||||
if hiddenAPIStubsTag, ok := tag.(hiddenAPIStubsDependencyTag); ok {
|
if hiddenAPIStubsTag, ok := tag.(hiddenAPIStubsDependencyTag); ok {
|
||||||
apiScope := hiddenAPIStubsTag.apiScope
|
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 {
|
if memberTag, ok := tag.(android.SdkMemberTypeDependencyTag); ok {
|
||||||
memberType := memberTag.SdkMemberType(child)
|
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.
|
// Make sure that the resolved module is allowed in the member list property.
|
||||||
if !memberType.IsInstance(child) {
|
if !memberType.IsInstance(child) {
|
||||||
ctx.ModuleErrorf("module %q is not valid in property %s", ctx.OtherModuleName(child), memberType.SdkPropertyName())
|
ctx.ModuleErrorf("module %q is not valid in property %s", ctx.OtherModuleName(child), memberType.SdkPropertyName())
|
||||||
|
Reference in New Issue
Block a user